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"
30af732203SDimitry Andric #include "llvm/ADT/APFixedPoint.h"
310b57cec5SDimitry Andric #include "llvm/ADT/Optional.h"
320b57cec5SDimitry Andric #include "llvm/IR/CFG.h"
330b57cec5SDimitry Andric #include "llvm/IR/Constants.h"
340b57cec5SDimitry Andric #include "llvm/IR/DataLayout.h"
35af732203SDimitry 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"
430b57cec5SDimitry Andric #include <cstdarg>
440b57cec5SDimitry Andric
450b57cec5SDimitry Andric using namespace clang;
460b57cec5SDimitry Andric using namespace CodeGen;
470b57cec5SDimitry Andric using llvm::Value;
480b57cec5SDimitry Andric
490b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
500b57cec5SDimitry Andric // Scalar Expression Emitter
510b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
520b57cec5SDimitry Andric
530b57cec5SDimitry Andric namespace {
540b57cec5SDimitry Andric
550b57cec5SDimitry Andric /// Determine whether the given binary operation may overflow.
560b57cec5SDimitry Andric /// Sets \p Result to the value of the operation for BO_Add, BO_Sub, BO_Mul,
570b57cec5SDimitry Andric /// and signed BO_{Div,Rem}. For these opcodes, and for unsigned BO_{Div,Rem},
580b57cec5SDimitry Andric /// the returned overflow check is precise. The returned value is 'true' for
590b57cec5SDimitry Andric /// all other opcodes, to be conservative.
mayHaveIntegerOverflow(llvm::ConstantInt * LHS,llvm::ConstantInt * RHS,BinaryOperator::Opcode Opcode,bool Signed,llvm::APInt & Result)600b57cec5SDimitry Andric bool mayHaveIntegerOverflow(llvm::ConstantInt *LHS, llvm::ConstantInt *RHS,
610b57cec5SDimitry Andric BinaryOperator::Opcode Opcode, bool Signed,
620b57cec5SDimitry Andric llvm::APInt &Result) {
630b57cec5SDimitry Andric // Assume overflow is possible, unless we can prove otherwise.
640b57cec5SDimitry Andric bool Overflow = true;
650b57cec5SDimitry Andric const auto &LHSAP = LHS->getValue();
660b57cec5SDimitry Andric const auto &RHSAP = RHS->getValue();
670b57cec5SDimitry Andric if (Opcode == BO_Add) {
680b57cec5SDimitry Andric if (Signed)
690b57cec5SDimitry Andric Result = LHSAP.sadd_ov(RHSAP, Overflow);
700b57cec5SDimitry Andric else
710b57cec5SDimitry Andric Result = LHSAP.uadd_ov(RHSAP, Overflow);
720b57cec5SDimitry Andric } else if (Opcode == BO_Sub) {
730b57cec5SDimitry Andric if (Signed)
740b57cec5SDimitry Andric Result = LHSAP.ssub_ov(RHSAP, Overflow);
750b57cec5SDimitry Andric else
760b57cec5SDimitry Andric Result = LHSAP.usub_ov(RHSAP, Overflow);
770b57cec5SDimitry Andric } else if (Opcode == BO_Mul) {
780b57cec5SDimitry Andric if (Signed)
790b57cec5SDimitry Andric Result = LHSAP.smul_ov(RHSAP, Overflow);
800b57cec5SDimitry Andric else
810b57cec5SDimitry Andric Result = LHSAP.umul_ov(RHSAP, Overflow);
820b57cec5SDimitry Andric } else if (Opcode == BO_Div || Opcode == BO_Rem) {
830b57cec5SDimitry Andric if (Signed && !RHS->isZero())
840b57cec5SDimitry Andric Result = LHSAP.sdiv_ov(RHSAP, Overflow);
850b57cec5SDimitry Andric else
860b57cec5SDimitry Andric return false;
870b57cec5SDimitry Andric }
880b57cec5SDimitry Andric return Overflow;
890b57cec5SDimitry Andric }
900b57cec5SDimitry Andric
910b57cec5SDimitry Andric struct BinOpInfo {
920b57cec5SDimitry Andric Value *LHS;
930b57cec5SDimitry Andric Value *RHS;
940b57cec5SDimitry Andric QualType Ty; // Computation Type.
950b57cec5SDimitry Andric BinaryOperator::Opcode Opcode; // Opcode of BinOp to perform
960b57cec5SDimitry Andric FPOptions FPFeatures;
970b57cec5SDimitry Andric const Expr *E; // Entire expr, for error unsupported. May not be binop.
980b57cec5SDimitry Andric
990b57cec5SDimitry Andric /// Check if the binop can result in integer overflow.
mayHaveIntegerOverflow__anon941989f10111::BinOpInfo1000b57cec5SDimitry Andric bool mayHaveIntegerOverflow() const {
1010b57cec5SDimitry Andric // Without constant input, we can't rule out overflow.
1020b57cec5SDimitry Andric auto *LHSCI = dyn_cast<llvm::ConstantInt>(LHS);
1030b57cec5SDimitry Andric auto *RHSCI = dyn_cast<llvm::ConstantInt>(RHS);
1040b57cec5SDimitry Andric if (!LHSCI || !RHSCI)
1050b57cec5SDimitry Andric return true;
1060b57cec5SDimitry Andric
1070b57cec5SDimitry Andric llvm::APInt Result;
1080b57cec5SDimitry Andric return ::mayHaveIntegerOverflow(
1090b57cec5SDimitry Andric LHSCI, RHSCI, Opcode, Ty->hasSignedIntegerRepresentation(), Result);
1100b57cec5SDimitry Andric }
1110b57cec5SDimitry Andric
1120b57cec5SDimitry Andric /// Check if the binop computes a division or a remainder.
isDivremOp__anon941989f10111::BinOpInfo1130b57cec5SDimitry Andric bool isDivremOp() const {
1140b57cec5SDimitry Andric return Opcode == BO_Div || Opcode == BO_Rem || Opcode == BO_DivAssign ||
1150b57cec5SDimitry Andric Opcode == BO_RemAssign;
1160b57cec5SDimitry Andric }
1170b57cec5SDimitry Andric
1180b57cec5SDimitry Andric /// Check if the binop can result in an integer division by zero.
mayHaveIntegerDivisionByZero__anon941989f10111::BinOpInfo1190b57cec5SDimitry Andric bool mayHaveIntegerDivisionByZero() const {
1200b57cec5SDimitry Andric if (isDivremOp())
1210b57cec5SDimitry Andric if (auto *CI = dyn_cast<llvm::ConstantInt>(RHS))
1220b57cec5SDimitry Andric return CI->isZero();
1230b57cec5SDimitry Andric return true;
1240b57cec5SDimitry Andric }
1250b57cec5SDimitry Andric
1260b57cec5SDimitry Andric /// Check if the binop can result in a float division by zero.
mayHaveFloatDivisionByZero__anon941989f10111::BinOpInfo1270b57cec5SDimitry Andric bool mayHaveFloatDivisionByZero() const {
1280b57cec5SDimitry Andric if (isDivremOp())
1290b57cec5SDimitry Andric if (auto *CFP = dyn_cast<llvm::ConstantFP>(RHS))
1300b57cec5SDimitry Andric return CFP->isZero();
1310b57cec5SDimitry Andric return true;
1320b57cec5SDimitry Andric }
1330b57cec5SDimitry Andric
1345ffd83dbSDimitry Andric /// Check if at least one operand is a fixed point type. In such cases, this
1355ffd83dbSDimitry Andric /// operation did not follow usual arithmetic conversion and both operands
1365ffd83dbSDimitry Andric /// might not be of the same type.
isFixedPointOp__anon941989f10111::BinOpInfo1375ffd83dbSDimitry Andric bool isFixedPointOp() const {
1380b57cec5SDimitry Andric // We cannot simply check the result type since comparison operations return
1390b57cec5SDimitry Andric // an int.
1400b57cec5SDimitry Andric if (const auto *BinOp = dyn_cast<BinaryOperator>(E)) {
1410b57cec5SDimitry Andric QualType LHSType = BinOp->getLHS()->getType();
1420b57cec5SDimitry Andric QualType RHSType = BinOp->getRHS()->getType();
1430b57cec5SDimitry Andric return LHSType->isFixedPointType() || RHSType->isFixedPointType();
1440b57cec5SDimitry Andric }
1455ffd83dbSDimitry Andric if (const auto *UnOp = dyn_cast<UnaryOperator>(E))
1465ffd83dbSDimitry Andric return UnOp->getSubExpr()->getType()->isFixedPointType();
1470b57cec5SDimitry Andric return false;
1480b57cec5SDimitry Andric }
1490b57cec5SDimitry Andric };
1500b57cec5SDimitry Andric
MustVisitNullValue(const Expr * E)1510b57cec5SDimitry Andric static bool MustVisitNullValue(const Expr *E) {
1520b57cec5SDimitry Andric // If a null pointer expression's type is the C++0x nullptr_t, then
1530b57cec5SDimitry Andric // it's not necessarily a simple constant and it must be evaluated
1540b57cec5SDimitry Andric // for its potential side effects.
1550b57cec5SDimitry Andric return E->getType()->isNullPtrType();
1560b57cec5SDimitry Andric }
1570b57cec5SDimitry Andric
1580b57cec5SDimitry Andric /// If \p E is a widened promoted integer, get its base (unpromoted) type.
getUnwidenedIntegerType(const ASTContext & Ctx,const Expr * E)1590b57cec5SDimitry Andric static llvm::Optional<QualType> getUnwidenedIntegerType(const ASTContext &Ctx,
1600b57cec5SDimitry Andric const Expr *E) {
1610b57cec5SDimitry Andric const Expr *Base = E->IgnoreImpCasts();
1620b57cec5SDimitry Andric if (E == Base)
1630b57cec5SDimitry Andric return llvm::None;
1640b57cec5SDimitry Andric
1650b57cec5SDimitry Andric QualType BaseTy = Base->getType();
1660b57cec5SDimitry Andric if (!BaseTy->isPromotableIntegerType() ||
1670b57cec5SDimitry Andric Ctx.getTypeSize(BaseTy) >= Ctx.getTypeSize(E->getType()))
1680b57cec5SDimitry Andric return llvm::None;
1690b57cec5SDimitry Andric
1700b57cec5SDimitry Andric return BaseTy;
1710b57cec5SDimitry Andric }
1720b57cec5SDimitry Andric
1730b57cec5SDimitry Andric /// Check if \p E is a widened promoted integer.
IsWidenedIntegerOp(const ASTContext & Ctx,const Expr * E)1740b57cec5SDimitry Andric static bool IsWidenedIntegerOp(const ASTContext &Ctx, const Expr *E) {
1750b57cec5SDimitry Andric return getUnwidenedIntegerType(Ctx, E).hasValue();
1760b57cec5SDimitry Andric }
1770b57cec5SDimitry Andric
1780b57cec5SDimitry Andric /// Check if we can skip the overflow check for \p Op.
CanElideOverflowCheck(const ASTContext & Ctx,const BinOpInfo & Op)1790b57cec5SDimitry Andric static bool CanElideOverflowCheck(const ASTContext &Ctx, const BinOpInfo &Op) {
1800b57cec5SDimitry Andric assert((isa<UnaryOperator>(Op.E) || isa<BinaryOperator>(Op.E)) &&
1810b57cec5SDimitry Andric "Expected a unary or binary operator");
1820b57cec5SDimitry Andric
1830b57cec5SDimitry Andric // If the binop has constant inputs and we can prove there is no overflow,
1840b57cec5SDimitry Andric // we can elide the overflow check.
1850b57cec5SDimitry Andric if (!Op.mayHaveIntegerOverflow())
1860b57cec5SDimitry Andric return true;
1870b57cec5SDimitry Andric
1880b57cec5SDimitry Andric // If a unary op has a widened operand, the op cannot overflow.
1890b57cec5SDimitry Andric if (const auto *UO = dyn_cast<UnaryOperator>(Op.E))
1900b57cec5SDimitry Andric return !UO->canOverflow();
1910b57cec5SDimitry Andric
1920b57cec5SDimitry Andric // We usually don't need overflow checks for binops with widened operands.
1930b57cec5SDimitry Andric // Multiplication with promoted unsigned operands is a special case.
1940b57cec5SDimitry Andric const auto *BO = cast<BinaryOperator>(Op.E);
1950b57cec5SDimitry Andric auto OptionalLHSTy = getUnwidenedIntegerType(Ctx, BO->getLHS());
1960b57cec5SDimitry Andric if (!OptionalLHSTy)
1970b57cec5SDimitry Andric return false;
1980b57cec5SDimitry Andric
1990b57cec5SDimitry Andric auto OptionalRHSTy = getUnwidenedIntegerType(Ctx, BO->getRHS());
2000b57cec5SDimitry Andric if (!OptionalRHSTy)
2010b57cec5SDimitry Andric return false;
2020b57cec5SDimitry Andric
2030b57cec5SDimitry Andric QualType LHSTy = *OptionalLHSTy;
2040b57cec5SDimitry Andric QualType RHSTy = *OptionalRHSTy;
2050b57cec5SDimitry Andric
2060b57cec5SDimitry Andric // This is the simple case: binops without unsigned multiplication, and with
2070b57cec5SDimitry Andric // widened operands. No overflow check is needed here.
2080b57cec5SDimitry Andric if ((Op.Opcode != BO_Mul && Op.Opcode != BO_MulAssign) ||
2090b57cec5SDimitry Andric !LHSTy->isUnsignedIntegerType() || !RHSTy->isUnsignedIntegerType())
2100b57cec5SDimitry Andric return true;
2110b57cec5SDimitry Andric
2120b57cec5SDimitry Andric // For unsigned multiplication the overflow check can be elided if either one
2130b57cec5SDimitry Andric // of the unpromoted types are less than half the size of the promoted type.
2140b57cec5SDimitry Andric unsigned PromotedSize = Ctx.getTypeSize(Op.E->getType());
2150b57cec5SDimitry Andric return (2 * Ctx.getTypeSize(LHSTy)) < PromotedSize ||
2160b57cec5SDimitry Andric (2 * Ctx.getTypeSize(RHSTy)) < PromotedSize;
2170b57cec5SDimitry Andric }
2180b57cec5SDimitry Andric
2190b57cec5SDimitry Andric class ScalarExprEmitter
2200b57cec5SDimitry Andric : public StmtVisitor<ScalarExprEmitter, Value*> {
2210b57cec5SDimitry Andric CodeGenFunction &CGF;
2220b57cec5SDimitry Andric CGBuilderTy &Builder;
2230b57cec5SDimitry Andric bool IgnoreResultAssign;
2240b57cec5SDimitry Andric llvm::LLVMContext &VMContext;
2250b57cec5SDimitry Andric public:
2260b57cec5SDimitry Andric
ScalarExprEmitter(CodeGenFunction & cgf,bool ira=false)2270b57cec5SDimitry Andric ScalarExprEmitter(CodeGenFunction &cgf, bool ira=false)
2280b57cec5SDimitry Andric : CGF(cgf), Builder(CGF.Builder), IgnoreResultAssign(ira),
2290b57cec5SDimitry Andric VMContext(cgf.getLLVMContext()) {
2300b57cec5SDimitry Andric }
2310b57cec5SDimitry Andric
2320b57cec5SDimitry Andric //===--------------------------------------------------------------------===//
2330b57cec5SDimitry Andric // Utilities
2340b57cec5SDimitry Andric //===--------------------------------------------------------------------===//
2350b57cec5SDimitry Andric
TestAndClearIgnoreResultAssign()2360b57cec5SDimitry Andric bool TestAndClearIgnoreResultAssign() {
2370b57cec5SDimitry Andric bool I = IgnoreResultAssign;
2380b57cec5SDimitry Andric IgnoreResultAssign = false;
2390b57cec5SDimitry Andric return I;
2400b57cec5SDimitry Andric }
2410b57cec5SDimitry Andric
ConvertType(QualType T)2420b57cec5SDimitry Andric llvm::Type *ConvertType(QualType T) { return CGF.ConvertType(T); }
EmitLValue(const Expr * E)2430b57cec5SDimitry Andric LValue EmitLValue(const Expr *E) { return CGF.EmitLValue(E); }
EmitCheckedLValue(const Expr * E,CodeGenFunction::TypeCheckKind TCK)2440b57cec5SDimitry Andric LValue EmitCheckedLValue(const Expr *E, CodeGenFunction::TypeCheckKind TCK) {
2450b57cec5SDimitry Andric return CGF.EmitCheckedLValue(E, TCK);
2460b57cec5SDimitry Andric }
2470b57cec5SDimitry Andric
2480b57cec5SDimitry Andric void EmitBinOpCheck(ArrayRef<std::pair<Value *, SanitizerMask>> Checks,
2490b57cec5SDimitry Andric const BinOpInfo &Info);
2500b57cec5SDimitry Andric
EmitLoadOfLValue(LValue LV,SourceLocation Loc)2510b57cec5SDimitry Andric Value *EmitLoadOfLValue(LValue LV, SourceLocation Loc) {
2520b57cec5SDimitry Andric return CGF.EmitLoadOfLValue(LV, Loc).getScalarVal();
2530b57cec5SDimitry Andric }
2540b57cec5SDimitry Andric
EmitLValueAlignmentAssumption(const Expr * E,Value * V)2550b57cec5SDimitry Andric void EmitLValueAlignmentAssumption(const Expr *E, Value *V) {
2560b57cec5SDimitry Andric const AlignValueAttr *AVAttr = nullptr;
2570b57cec5SDimitry Andric if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) {
2580b57cec5SDimitry Andric const ValueDecl *VD = DRE->getDecl();
2590b57cec5SDimitry Andric
2600b57cec5SDimitry Andric if (VD->getType()->isReferenceType()) {
2610b57cec5SDimitry Andric if (const auto *TTy =
2620b57cec5SDimitry Andric dyn_cast<TypedefType>(VD->getType().getNonReferenceType()))
2630b57cec5SDimitry Andric AVAttr = TTy->getDecl()->getAttr<AlignValueAttr>();
2640b57cec5SDimitry Andric } else {
2650b57cec5SDimitry Andric // Assumptions for function parameters are emitted at the start of the
2660b57cec5SDimitry Andric // function, so there is no need to repeat that here,
2670b57cec5SDimitry Andric // unless the alignment-assumption sanitizer is enabled,
2680b57cec5SDimitry Andric // then we prefer the assumption over alignment attribute
2690b57cec5SDimitry Andric // on IR function param.
2700b57cec5SDimitry Andric if (isa<ParmVarDecl>(VD) && !CGF.SanOpts.has(SanitizerKind::Alignment))
2710b57cec5SDimitry Andric return;
2720b57cec5SDimitry Andric
2730b57cec5SDimitry Andric AVAttr = VD->getAttr<AlignValueAttr>();
2740b57cec5SDimitry Andric }
2750b57cec5SDimitry Andric }
2760b57cec5SDimitry Andric
2770b57cec5SDimitry Andric if (!AVAttr)
2780b57cec5SDimitry Andric if (const auto *TTy =
2790b57cec5SDimitry Andric dyn_cast<TypedefType>(E->getType()))
2800b57cec5SDimitry Andric AVAttr = TTy->getDecl()->getAttr<AlignValueAttr>();
2810b57cec5SDimitry Andric
2820b57cec5SDimitry Andric if (!AVAttr)
2830b57cec5SDimitry Andric return;
2840b57cec5SDimitry Andric
2850b57cec5SDimitry Andric Value *AlignmentValue = CGF.EmitScalarExpr(AVAttr->getAlignment());
2860b57cec5SDimitry Andric llvm::ConstantInt *AlignmentCI = cast<llvm::ConstantInt>(AlignmentValue);
2875ffd83dbSDimitry Andric CGF.emitAlignmentAssumption(V, E, AVAttr->getLocation(), AlignmentCI);
2880b57cec5SDimitry Andric }
2890b57cec5SDimitry Andric
2900b57cec5SDimitry Andric /// EmitLoadOfLValue - Given an expression with complex type that represents a
2910b57cec5SDimitry Andric /// value l-value, this method emits the address of the l-value, then loads
2920b57cec5SDimitry Andric /// and returns the result.
EmitLoadOfLValue(const Expr * E)2930b57cec5SDimitry Andric Value *EmitLoadOfLValue(const Expr *E) {
2940b57cec5SDimitry Andric Value *V = EmitLoadOfLValue(EmitCheckedLValue(E, CodeGenFunction::TCK_Load),
2950b57cec5SDimitry Andric E->getExprLoc());
2960b57cec5SDimitry Andric
2970b57cec5SDimitry Andric EmitLValueAlignmentAssumption(E, V);
2980b57cec5SDimitry Andric return V;
2990b57cec5SDimitry Andric }
3000b57cec5SDimitry Andric
3010b57cec5SDimitry Andric /// EmitConversionToBool - Convert the specified expression value to a
3020b57cec5SDimitry Andric /// boolean (i1) truth value. This is equivalent to "Val != 0".
3030b57cec5SDimitry Andric Value *EmitConversionToBool(Value *Src, QualType DstTy);
3040b57cec5SDimitry Andric
3050b57cec5SDimitry Andric /// Emit a check that a conversion from a floating-point type does not
3060b57cec5SDimitry Andric /// overflow.
3070b57cec5SDimitry Andric void EmitFloatConversionCheck(Value *OrigSrc, QualType OrigSrcType,
3080b57cec5SDimitry Andric Value *Src, QualType SrcType, QualType DstType,
3090b57cec5SDimitry Andric llvm::Type *DstTy, SourceLocation Loc);
3100b57cec5SDimitry Andric
3110b57cec5SDimitry Andric /// Known implicit conversion check kinds.
3120b57cec5SDimitry Andric /// Keep in sync with the enum of the same name in ubsan_handlers.h
3130b57cec5SDimitry Andric enum ImplicitConversionCheckKind : unsigned char {
3140b57cec5SDimitry Andric ICCK_IntegerTruncation = 0, // Legacy, was only used by clang 7.
3150b57cec5SDimitry Andric ICCK_UnsignedIntegerTruncation = 1,
3160b57cec5SDimitry Andric ICCK_SignedIntegerTruncation = 2,
3170b57cec5SDimitry Andric ICCK_IntegerSignChange = 3,
3180b57cec5SDimitry Andric ICCK_SignedIntegerTruncationOrSignChange = 4,
3190b57cec5SDimitry Andric };
3200b57cec5SDimitry Andric
3210b57cec5SDimitry Andric /// Emit a check that an [implicit] truncation of an integer does not
3220b57cec5SDimitry Andric /// discard any bits. It is not UB, so we use the value after truncation.
3230b57cec5SDimitry Andric void EmitIntegerTruncationCheck(Value *Src, QualType SrcType, Value *Dst,
3240b57cec5SDimitry Andric QualType DstType, SourceLocation Loc);
3250b57cec5SDimitry Andric
3260b57cec5SDimitry Andric /// Emit a check that an [implicit] conversion of an integer does not change
3270b57cec5SDimitry Andric /// the sign of the value. It is not UB, so we use the value after conversion.
3280b57cec5SDimitry Andric /// NOTE: Src and Dst may be the exact same value! (point to the same thing)
3290b57cec5SDimitry Andric void EmitIntegerSignChangeCheck(Value *Src, QualType SrcType, Value *Dst,
3300b57cec5SDimitry Andric QualType DstType, SourceLocation Loc);
3310b57cec5SDimitry Andric
3320b57cec5SDimitry Andric /// Emit a conversion from the specified type to the specified destination
3330b57cec5SDimitry Andric /// type, both of which are LLVM scalar types.
3340b57cec5SDimitry Andric struct ScalarConversionOpts {
3350b57cec5SDimitry Andric bool TreatBooleanAsSigned;
3360b57cec5SDimitry Andric bool EmitImplicitIntegerTruncationChecks;
3370b57cec5SDimitry Andric bool EmitImplicitIntegerSignChangeChecks;
3380b57cec5SDimitry Andric
ScalarConversionOpts__anon941989f10111::ScalarExprEmitter::ScalarConversionOpts3390b57cec5SDimitry Andric ScalarConversionOpts()
3400b57cec5SDimitry Andric : TreatBooleanAsSigned(false),
3410b57cec5SDimitry Andric EmitImplicitIntegerTruncationChecks(false),
3420b57cec5SDimitry Andric EmitImplicitIntegerSignChangeChecks(false) {}
3430b57cec5SDimitry Andric
ScalarConversionOpts__anon941989f10111::ScalarExprEmitter::ScalarConversionOpts3440b57cec5SDimitry Andric ScalarConversionOpts(clang::SanitizerSet SanOpts)
3450b57cec5SDimitry Andric : TreatBooleanAsSigned(false),
3460b57cec5SDimitry Andric EmitImplicitIntegerTruncationChecks(
3470b57cec5SDimitry Andric SanOpts.hasOneOf(SanitizerKind::ImplicitIntegerTruncation)),
3480b57cec5SDimitry Andric EmitImplicitIntegerSignChangeChecks(
3490b57cec5SDimitry Andric SanOpts.has(SanitizerKind::ImplicitIntegerSignChange)) {}
3500b57cec5SDimitry Andric };
351*5f7ddb14SDimitry Andric Value *EmitScalarCast(Value *Src, QualType SrcType, QualType DstType,
352*5f7ddb14SDimitry Andric llvm::Type *SrcTy, llvm::Type *DstTy,
353*5f7ddb14SDimitry Andric ScalarConversionOpts Opts);
3540b57cec5SDimitry Andric Value *
3550b57cec5SDimitry Andric EmitScalarConversion(Value *Src, QualType SrcTy, QualType DstTy,
3560b57cec5SDimitry Andric SourceLocation Loc,
3570b57cec5SDimitry Andric ScalarConversionOpts Opts = ScalarConversionOpts());
3580b57cec5SDimitry Andric
3590b57cec5SDimitry Andric /// Convert between either a fixed point and other fixed point or fixed point
3600b57cec5SDimitry Andric /// and an integer.
3610b57cec5SDimitry Andric Value *EmitFixedPointConversion(Value *Src, QualType SrcTy, QualType DstTy,
3620b57cec5SDimitry Andric SourceLocation Loc);
3630b57cec5SDimitry Andric
3640b57cec5SDimitry Andric /// Emit a conversion from the specified complex type to the specified
3650b57cec5SDimitry Andric /// destination type, where the destination type is an LLVM scalar type.
3660b57cec5SDimitry Andric Value *EmitComplexToScalarConversion(CodeGenFunction::ComplexPairTy Src,
3670b57cec5SDimitry Andric QualType SrcTy, QualType DstTy,
3680b57cec5SDimitry Andric SourceLocation Loc);
3690b57cec5SDimitry Andric
3700b57cec5SDimitry Andric /// EmitNullValue - Emit a value that corresponds to null for the given type.
3710b57cec5SDimitry Andric Value *EmitNullValue(QualType Ty);
3720b57cec5SDimitry Andric
3730b57cec5SDimitry Andric /// EmitFloatToBoolConversion - Perform an FP to boolean conversion.
EmitFloatToBoolConversion(Value * V)3740b57cec5SDimitry Andric Value *EmitFloatToBoolConversion(Value *V) {
3750b57cec5SDimitry Andric // Compare against 0.0 for fp scalars.
3760b57cec5SDimitry Andric llvm::Value *Zero = llvm::Constant::getNullValue(V->getType());
3770b57cec5SDimitry Andric return Builder.CreateFCmpUNE(V, Zero, "tobool");
3780b57cec5SDimitry Andric }
3790b57cec5SDimitry Andric
3800b57cec5SDimitry Andric /// EmitPointerToBoolConversion - Perform a pointer to boolean conversion.
EmitPointerToBoolConversion(Value * V,QualType QT)3810b57cec5SDimitry Andric Value *EmitPointerToBoolConversion(Value *V, QualType QT) {
3820b57cec5SDimitry Andric Value *Zero = CGF.CGM.getNullPointer(cast<llvm::PointerType>(V->getType()), QT);
3830b57cec5SDimitry Andric
3840b57cec5SDimitry Andric return Builder.CreateICmpNE(V, Zero, "tobool");
3850b57cec5SDimitry Andric }
3860b57cec5SDimitry Andric
EmitIntToBoolConversion(Value * V)3870b57cec5SDimitry Andric Value *EmitIntToBoolConversion(Value *V) {
3880b57cec5SDimitry Andric // Because of the type rules of C, we often end up computing a
3890b57cec5SDimitry Andric // logical value, then zero extending it to int, then wanting it
3900b57cec5SDimitry Andric // as a logical value again. Optimize this common case.
3910b57cec5SDimitry Andric if (llvm::ZExtInst *ZI = dyn_cast<llvm::ZExtInst>(V)) {
3920b57cec5SDimitry Andric if (ZI->getOperand(0)->getType() == Builder.getInt1Ty()) {
3930b57cec5SDimitry Andric Value *Result = ZI->getOperand(0);
3940b57cec5SDimitry Andric // If there aren't any more uses, zap the instruction to save space.
3950b57cec5SDimitry Andric // Note that there can be more uses, for example if this
3960b57cec5SDimitry Andric // is the result of an assignment.
3970b57cec5SDimitry Andric if (ZI->use_empty())
3980b57cec5SDimitry Andric ZI->eraseFromParent();
3990b57cec5SDimitry Andric return Result;
4000b57cec5SDimitry Andric }
4010b57cec5SDimitry Andric }
4020b57cec5SDimitry Andric
4030b57cec5SDimitry Andric return Builder.CreateIsNotNull(V, "tobool");
4040b57cec5SDimitry Andric }
4050b57cec5SDimitry Andric
4060b57cec5SDimitry Andric //===--------------------------------------------------------------------===//
4070b57cec5SDimitry Andric // Visitor Methods
4080b57cec5SDimitry Andric //===--------------------------------------------------------------------===//
4090b57cec5SDimitry Andric
Visit(Expr * E)4100b57cec5SDimitry Andric Value *Visit(Expr *E) {
4110b57cec5SDimitry Andric ApplyDebugLocation DL(CGF, E);
4120b57cec5SDimitry Andric return StmtVisitor<ScalarExprEmitter, Value*>::Visit(E);
4130b57cec5SDimitry Andric }
4140b57cec5SDimitry Andric
VisitStmt(Stmt * S)4150b57cec5SDimitry Andric Value *VisitStmt(Stmt *S) {
4165ffd83dbSDimitry Andric S->dump(llvm::errs(), CGF.getContext());
4170b57cec5SDimitry Andric llvm_unreachable("Stmt can't have complex result type!");
4180b57cec5SDimitry Andric }
4190b57cec5SDimitry Andric Value *VisitExpr(Expr *S);
4200b57cec5SDimitry Andric
VisitConstantExpr(ConstantExpr * E)4210b57cec5SDimitry Andric Value *VisitConstantExpr(ConstantExpr *E) {
4225ffd83dbSDimitry Andric if (Value *Result = ConstantEmitter(CGF).tryEmitConstantExpr(E)) {
4235ffd83dbSDimitry Andric if (E->isGLValue())
4245ffd83dbSDimitry Andric return CGF.Builder.CreateLoad(Address(
4255ffd83dbSDimitry Andric Result, CGF.getContext().getTypeAlignInChars(E->getType())));
4265ffd83dbSDimitry Andric return Result;
4275ffd83dbSDimitry Andric }
4280b57cec5SDimitry Andric return Visit(E->getSubExpr());
4290b57cec5SDimitry Andric }
VisitParenExpr(ParenExpr * PE)4300b57cec5SDimitry Andric Value *VisitParenExpr(ParenExpr *PE) {
4310b57cec5SDimitry Andric return Visit(PE->getSubExpr());
4320b57cec5SDimitry Andric }
VisitSubstNonTypeTemplateParmExpr(SubstNonTypeTemplateParmExpr * E)4330b57cec5SDimitry Andric Value *VisitSubstNonTypeTemplateParmExpr(SubstNonTypeTemplateParmExpr *E) {
4340b57cec5SDimitry Andric return Visit(E->getReplacement());
4350b57cec5SDimitry Andric }
VisitGenericSelectionExpr(GenericSelectionExpr * GE)4360b57cec5SDimitry Andric Value *VisitGenericSelectionExpr(GenericSelectionExpr *GE) {
4370b57cec5SDimitry Andric return Visit(GE->getResultExpr());
4380b57cec5SDimitry Andric }
VisitCoawaitExpr(CoawaitExpr * S)4390b57cec5SDimitry Andric Value *VisitCoawaitExpr(CoawaitExpr *S) {
4400b57cec5SDimitry Andric return CGF.EmitCoawaitExpr(*S).getScalarVal();
4410b57cec5SDimitry Andric }
VisitCoyieldExpr(CoyieldExpr * S)4420b57cec5SDimitry Andric Value *VisitCoyieldExpr(CoyieldExpr *S) {
4430b57cec5SDimitry Andric return CGF.EmitCoyieldExpr(*S).getScalarVal();
4440b57cec5SDimitry Andric }
VisitUnaryCoawait(const UnaryOperator * E)4450b57cec5SDimitry Andric Value *VisitUnaryCoawait(const UnaryOperator *E) {
4460b57cec5SDimitry Andric return Visit(E->getSubExpr());
4470b57cec5SDimitry Andric }
4480b57cec5SDimitry Andric
4490b57cec5SDimitry Andric // Leaves.
VisitIntegerLiteral(const IntegerLiteral * E)4500b57cec5SDimitry Andric Value *VisitIntegerLiteral(const IntegerLiteral *E) {
4510b57cec5SDimitry Andric return Builder.getInt(E->getValue());
4520b57cec5SDimitry Andric }
VisitFixedPointLiteral(const FixedPointLiteral * E)4530b57cec5SDimitry Andric Value *VisitFixedPointLiteral(const FixedPointLiteral *E) {
4540b57cec5SDimitry Andric return Builder.getInt(E->getValue());
4550b57cec5SDimitry Andric }
VisitFloatingLiteral(const FloatingLiteral * E)4560b57cec5SDimitry Andric Value *VisitFloatingLiteral(const FloatingLiteral *E) {
4570b57cec5SDimitry Andric return llvm::ConstantFP::get(VMContext, E->getValue());
4580b57cec5SDimitry Andric }
VisitCharacterLiteral(const CharacterLiteral * E)4590b57cec5SDimitry Andric Value *VisitCharacterLiteral(const CharacterLiteral *E) {
4600b57cec5SDimitry Andric return llvm::ConstantInt::get(ConvertType(E->getType()), E->getValue());
4610b57cec5SDimitry Andric }
VisitObjCBoolLiteralExpr(const ObjCBoolLiteralExpr * E)4620b57cec5SDimitry Andric Value *VisitObjCBoolLiteralExpr(const ObjCBoolLiteralExpr *E) {
4630b57cec5SDimitry Andric return llvm::ConstantInt::get(ConvertType(E->getType()), E->getValue());
4640b57cec5SDimitry Andric }
VisitCXXBoolLiteralExpr(const CXXBoolLiteralExpr * E)4650b57cec5SDimitry Andric Value *VisitCXXBoolLiteralExpr(const CXXBoolLiteralExpr *E) {
4660b57cec5SDimitry Andric return llvm::ConstantInt::get(ConvertType(E->getType()), E->getValue());
4670b57cec5SDimitry Andric }
VisitCXXScalarValueInitExpr(const CXXScalarValueInitExpr * E)4680b57cec5SDimitry Andric Value *VisitCXXScalarValueInitExpr(const CXXScalarValueInitExpr *E) {
4690b57cec5SDimitry Andric return EmitNullValue(E->getType());
4700b57cec5SDimitry Andric }
VisitGNUNullExpr(const GNUNullExpr * E)4710b57cec5SDimitry Andric Value *VisitGNUNullExpr(const GNUNullExpr *E) {
4720b57cec5SDimitry Andric return EmitNullValue(E->getType());
4730b57cec5SDimitry Andric }
4740b57cec5SDimitry Andric Value *VisitOffsetOfExpr(OffsetOfExpr *E);
4750b57cec5SDimitry Andric Value *VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *E);
VisitAddrLabelExpr(const AddrLabelExpr * E)4760b57cec5SDimitry Andric Value *VisitAddrLabelExpr(const AddrLabelExpr *E) {
4770b57cec5SDimitry Andric llvm::Value *V = CGF.GetAddrOfLabel(E->getLabel());
4780b57cec5SDimitry Andric return Builder.CreateBitCast(V, ConvertType(E->getType()));
4790b57cec5SDimitry Andric }
4800b57cec5SDimitry Andric
VisitSizeOfPackExpr(SizeOfPackExpr * E)4810b57cec5SDimitry Andric Value *VisitSizeOfPackExpr(SizeOfPackExpr *E) {
4820b57cec5SDimitry Andric return llvm::ConstantInt::get(ConvertType(E->getType()),E->getPackLength());
4830b57cec5SDimitry Andric }
4840b57cec5SDimitry Andric
VisitPseudoObjectExpr(PseudoObjectExpr * E)4850b57cec5SDimitry Andric Value *VisitPseudoObjectExpr(PseudoObjectExpr *E) {
4860b57cec5SDimitry Andric return CGF.EmitPseudoObjectRValue(E).getScalarVal();
4870b57cec5SDimitry Andric }
4880b57cec5SDimitry Andric
489*5f7ddb14SDimitry Andric Value *VisitSYCLUniqueStableNameExpr(SYCLUniqueStableNameExpr *E);
490*5f7ddb14SDimitry Andric
VisitOpaqueValueExpr(OpaqueValueExpr * E)4910b57cec5SDimitry Andric Value *VisitOpaqueValueExpr(OpaqueValueExpr *E) {
4920b57cec5SDimitry Andric if (E->isGLValue())
4930b57cec5SDimitry Andric return EmitLoadOfLValue(CGF.getOrCreateOpaqueLValueMapping(E),
4940b57cec5SDimitry Andric E->getExprLoc());
4950b57cec5SDimitry Andric
4960b57cec5SDimitry Andric // Otherwise, assume the mapping is the scalar directly.
4970b57cec5SDimitry Andric return CGF.getOrCreateOpaqueRValueMapping(E).getScalarVal();
4980b57cec5SDimitry Andric }
4990b57cec5SDimitry Andric
5000b57cec5SDimitry Andric // l-values.
VisitDeclRefExpr(DeclRefExpr * E)5010b57cec5SDimitry Andric Value *VisitDeclRefExpr(DeclRefExpr *E) {
5020b57cec5SDimitry Andric if (CodeGenFunction::ConstantEmission Constant = CGF.tryEmitAsConstant(E))
5030b57cec5SDimitry Andric return CGF.emitScalarConstant(Constant, E);
5040b57cec5SDimitry Andric return EmitLoadOfLValue(E);
5050b57cec5SDimitry Andric }
5060b57cec5SDimitry Andric
VisitObjCSelectorExpr(ObjCSelectorExpr * E)5070b57cec5SDimitry Andric Value *VisitObjCSelectorExpr(ObjCSelectorExpr *E) {
5080b57cec5SDimitry Andric return CGF.EmitObjCSelectorExpr(E);
5090b57cec5SDimitry Andric }
VisitObjCProtocolExpr(ObjCProtocolExpr * E)5100b57cec5SDimitry Andric Value *VisitObjCProtocolExpr(ObjCProtocolExpr *E) {
5110b57cec5SDimitry Andric return CGF.EmitObjCProtocolExpr(E);
5120b57cec5SDimitry Andric }
VisitObjCIvarRefExpr(ObjCIvarRefExpr * E)5130b57cec5SDimitry Andric Value *VisitObjCIvarRefExpr(ObjCIvarRefExpr *E) {
5140b57cec5SDimitry Andric return EmitLoadOfLValue(E);
5150b57cec5SDimitry Andric }
VisitObjCMessageExpr(ObjCMessageExpr * E)5160b57cec5SDimitry Andric Value *VisitObjCMessageExpr(ObjCMessageExpr *E) {
5170b57cec5SDimitry Andric if (E->getMethodDecl() &&
5180b57cec5SDimitry Andric E->getMethodDecl()->getReturnType()->isReferenceType())
5190b57cec5SDimitry Andric return EmitLoadOfLValue(E);
5200b57cec5SDimitry Andric return CGF.EmitObjCMessageExpr(E).getScalarVal();
5210b57cec5SDimitry Andric }
5220b57cec5SDimitry Andric
VisitObjCIsaExpr(ObjCIsaExpr * E)5230b57cec5SDimitry Andric Value *VisitObjCIsaExpr(ObjCIsaExpr *E) {
5240b57cec5SDimitry Andric LValue LV = CGF.EmitObjCIsaExpr(E);
5250b57cec5SDimitry Andric Value *V = CGF.EmitLoadOfLValue(LV, E->getExprLoc()).getScalarVal();
5260b57cec5SDimitry Andric return V;
5270b57cec5SDimitry Andric }
5280b57cec5SDimitry Andric
VisitObjCAvailabilityCheckExpr(ObjCAvailabilityCheckExpr * E)5290b57cec5SDimitry Andric Value *VisitObjCAvailabilityCheckExpr(ObjCAvailabilityCheckExpr *E) {
5300b57cec5SDimitry Andric VersionTuple Version = E->getVersion();
5310b57cec5SDimitry Andric
5320b57cec5SDimitry Andric // If we're checking for a platform older than our minimum deployment
5330b57cec5SDimitry Andric // target, we can fold the check away.
5340b57cec5SDimitry Andric if (Version <= CGF.CGM.getTarget().getPlatformMinVersion())
5350b57cec5SDimitry Andric return llvm::ConstantInt::get(Builder.getInt1Ty(), 1);
5360b57cec5SDimitry Andric
537af732203SDimitry Andric return CGF.EmitBuiltinAvailable(Version);
5380b57cec5SDimitry Andric }
5390b57cec5SDimitry Andric
5400b57cec5SDimitry Andric Value *VisitArraySubscriptExpr(ArraySubscriptExpr *E);
5415ffd83dbSDimitry Andric Value *VisitMatrixSubscriptExpr(MatrixSubscriptExpr *E);
5420b57cec5SDimitry Andric Value *VisitShuffleVectorExpr(ShuffleVectorExpr *E);
5430b57cec5SDimitry Andric Value *VisitConvertVectorExpr(ConvertVectorExpr *E);
5440b57cec5SDimitry Andric Value *VisitMemberExpr(MemberExpr *E);
VisitExtVectorElementExpr(Expr * E)5450b57cec5SDimitry Andric Value *VisitExtVectorElementExpr(Expr *E) { return EmitLoadOfLValue(E); }
VisitCompoundLiteralExpr(CompoundLiteralExpr * E)5460b57cec5SDimitry Andric Value *VisitCompoundLiteralExpr(CompoundLiteralExpr *E) {
5475ffd83dbSDimitry Andric // Strictly speaking, we shouldn't be calling EmitLoadOfLValue, which
5485ffd83dbSDimitry Andric // transitively calls EmitCompoundLiteralLValue, here in C++ since compound
5495ffd83dbSDimitry Andric // literals aren't l-values in C++. We do so simply because that's the
5505ffd83dbSDimitry Andric // cleanest way to handle compound literals in C++.
5515ffd83dbSDimitry Andric // See the discussion here: https://reviews.llvm.org/D64464
5520b57cec5SDimitry Andric return EmitLoadOfLValue(E);
5530b57cec5SDimitry Andric }
5540b57cec5SDimitry Andric
5550b57cec5SDimitry Andric Value *VisitInitListExpr(InitListExpr *E);
5560b57cec5SDimitry Andric
VisitArrayInitIndexExpr(ArrayInitIndexExpr * E)5570b57cec5SDimitry Andric Value *VisitArrayInitIndexExpr(ArrayInitIndexExpr *E) {
5580b57cec5SDimitry Andric assert(CGF.getArrayInitIndex() &&
5590b57cec5SDimitry Andric "ArrayInitIndexExpr not inside an ArrayInitLoopExpr?");
5600b57cec5SDimitry Andric return CGF.getArrayInitIndex();
5610b57cec5SDimitry Andric }
5620b57cec5SDimitry Andric
VisitImplicitValueInitExpr(const ImplicitValueInitExpr * E)5630b57cec5SDimitry Andric Value *VisitImplicitValueInitExpr(const ImplicitValueInitExpr *E) {
5640b57cec5SDimitry Andric return EmitNullValue(E->getType());
5650b57cec5SDimitry Andric }
VisitExplicitCastExpr(ExplicitCastExpr * E)5660b57cec5SDimitry Andric Value *VisitExplicitCastExpr(ExplicitCastExpr *E) {
5670b57cec5SDimitry Andric CGF.CGM.EmitExplicitCastExprType(E, &CGF);
5680b57cec5SDimitry Andric return VisitCastExpr(E);
5690b57cec5SDimitry Andric }
5700b57cec5SDimitry Andric Value *VisitCastExpr(CastExpr *E);
5710b57cec5SDimitry Andric
VisitCallExpr(const CallExpr * E)5720b57cec5SDimitry Andric Value *VisitCallExpr(const CallExpr *E) {
5730b57cec5SDimitry Andric if (E->getCallReturnType(CGF.getContext())->isReferenceType())
5740b57cec5SDimitry Andric return EmitLoadOfLValue(E);
5750b57cec5SDimitry Andric
5760b57cec5SDimitry Andric Value *V = CGF.EmitCallExpr(E).getScalarVal();
5770b57cec5SDimitry Andric
5780b57cec5SDimitry Andric EmitLValueAlignmentAssumption(E, V);
5790b57cec5SDimitry Andric return V;
5800b57cec5SDimitry Andric }
5810b57cec5SDimitry Andric
5820b57cec5SDimitry Andric Value *VisitStmtExpr(const StmtExpr *E);
5830b57cec5SDimitry Andric
5840b57cec5SDimitry Andric // Unary Operators.
VisitUnaryPostDec(const UnaryOperator * E)5850b57cec5SDimitry Andric Value *VisitUnaryPostDec(const UnaryOperator *E) {
5860b57cec5SDimitry Andric LValue LV = EmitLValue(E->getSubExpr());
5870b57cec5SDimitry Andric return EmitScalarPrePostIncDec(E, LV, false, false);
5880b57cec5SDimitry Andric }
VisitUnaryPostInc(const UnaryOperator * E)5890b57cec5SDimitry Andric Value *VisitUnaryPostInc(const UnaryOperator *E) {
5900b57cec5SDimitry Andric LValue LV = EmitLValue(E->getSubExpr());
5910b57cec5SDimitry Andric return EmitScalarPrePostIncDec(E, LV, true, false);
5920b57cec5SDimitry Andric }
VisitUnaryPreDec(const UnaryOperator * E)5930b57cec5SDimitry Andric Value *VisitUnaryPreDec(const UnaryOperator *E) {
5940b57cec5SDimitry Andric LValue LV = EmitLValue(E->getSubExpr());
5950b57cec5SDimitry Andric return EmitScalarPrePostIncDec(E, LV, false, true);
5960b57cec5SDimitry Andric }
VisitUnaryPreInc(const UnaryOperator * E)5970b57cec5SDimitry Andric Value *VisitUnaryPreInc(const UnaryOperator *E) {
5980b57cec5SDimitry Andric LValue LV = EmitLValue(E->getSubExpr());
5990b57cec5SDimitry Andric return EmitScalarPrePostIncDec(E, LV, true, true);
6000b57cec5SDimitry Andric }
6010b57cec5SDimitry Andric
6020b57cec5SDimitry Andric llvm::Value *EmitIncDecConsiderOverflowBehavior(const UnaryOperator *E,
6030b57cec5SDimitry Andric llvm::Value *InVal,
6040b57cec5SDimitry Andric bool IsInc);
6050b57cec5SDimitry Andric
6060b57cec5SDimitry Andric llvm::Value *EmitScalarPrePostIncDec(const UnaryOperator *E, LValue LV,
6070b57cec5SDimitry Andric bool isInc, bool isPre);
6080b57cec5SDimitry Andric
6090b57cec5SDimitry Andric
VisitUnaryAddrOf(const UnaryOperator * E)6100b57cec5SDimitry Andric Value *VisitUnaryAddrOf(const UnaryOperator *E) {
6110b57cec5SDimitry Andric if (isa<MemberPointerType>(E->getType())) // never sugared
6120b57cec5SDimitry Andric return CGF.CGM.getMemberPointerConstant(E);
6130b57cec5SDimitry Andric
614480093f4SDimitry Andric return EmitLValue(E->getSubExpr()).getPointer(CGF);
6150b57cec5SDimitry Andric }
VisitUnaryDeref(const UnaryOperator * E)6160b57cec5SDimitry Andric Value *VisitUnaryDeref(const UnaryOperator *E) {
6170b57cec5SDimitry Andric if (E->getType()->isVoidType())
6180b57cec5SDimitry Andric return Visit(E->getSubExpr()); // the actual value should be unused
6190b57cec5SDimitry Andric return EmitLoadOfLValue(E);
6200b57cec5SDimitry Andric }
VisitUnaryPlus(const UnaryOperator * E)6210b57cec5SDimitry Andric Value *VisitUnaryPlus(const UnaryOperator *E) {
6220b57cec5SDimitry Andric // This differs from gcc, though, most likely due to a bug in gcc.
6230b57cec5SDimitry Andric TestAndClearIgnoreResultAssign();
6240b57cec5SDimitry Andric return Visit(E->getSubExpr());
6250b57cec5SDimitry Andric }
6260b57cec5SDimitry Andric Value *VisitUnaryMinus (const UnaryOperator *E);
6270b57cec5SDimitry Andric Value *VisitUnaryNot (const UnaryOperator *E);
6280b57cec5SDimitry Andric Value *VisitUnaryLNot (const UnaryOperator *E);
6290b57cec5SDimitry Andric Value *VisitUnaryReal (const UnaryOperator *E);
6300b57cec5SDimitry Andric Value *VisitUnaryImag (const UnaryOperator *E);
VisitUnaryExtension(const UnaryOperator * E)6310b57cec5SDimitry Andric Value *VisitUnaryExtension(const UnaryOperator *E) {
6320b57cec5SDimitry Andric return Visit(E->getSubExpr());
6330b57cec5SDimitry Andric }
6340b57cec5SDimitry Andric
6350b57cec5SDimitry Andric // C++
VisitMaterializeTemporaryExpr(const MaterializeTemporaryExpr * E)6360b57cec5SDimitry Andric Value *VisitMaterializeTemporaryExpr(const MaterializeTemporaryExpr *E) {
6370b57cec5SDimitry Andric return EmitLoadOfLValue(E);
6380b57cec5SDimitry Andric }
VisitSourceLocExpr(SourceLocExpr * SLE)6390b57cec5SDimitry Andric Value *VisitSourceLocExpr(SourceLocExpr *SLE) {
6400b57cec5SDimitry Andric auto &Ctx = CGF.getContext();
6410b57cec5SDimitry Andric APValue Evaluated =
6420b57cec5SDimitry Andric SLE->EvaluateInContext(Ctx, CGF.CurSourceLocExprScope.getDefaultExpr());
643480093f4SDimitry Andric return ConstantEmitter(CGF).emitAbstract(SLE->getLocation(), Evaluated,
644480093f4SDimitry Andric SLE->getType());
6450b57cec5SDimitry Andric }
6460b57cec5SDimitry Andric
VisitCXXDefaultArgExpr(CXXDefaultArgExpr * DAE)6470b57cec5SDimitry Andric Value *VisitCXXDefaultArgExpr(CXXDefaultArgExpr *DAE) {
6480b57cec5SDimitry Andric CodeGenFunction::CXXDefaultArgExprScope Scope(CGF, DAE);
6490b57cec5SDimitry Andric return Visit(DAE->getExpr());
6500b57cec5SDimitry Andric }
VisitCXXDefaultInitExpr(CXXDefaultInitExpr * DIE)6510b57cec5SDimitry Andric Value *VisitCXXDefaultInitExpr(CXXDefaultInitExpr *DIE) {
6520b57cec5SDimitry Andric CodeGenFunction::CXXDefaultInitExprScope Scope(CGF, DIE);
6530b57cec5SDimitry Andric return Visit(DIE->getExpr());
6540b57cec5SDimitry Andric }
VisitCXXThisExpr(CXXThisExpr * TE)6550b57cec5SDimitry Andric Value *VisitCXXThisExpr(CXXThisExpr *TE) {
6560b57cec5SDimitry Andric return CGF.LoadCXXThis();
6570b57cec5SDimitry Andric }
6580b57cec5SDimitry Andric
6590b57cec5SDimitry Andric Value *VisitExprWithCleanups(ExprWithCleanups *E);
VisitCXXNewExpr(const CXXNewExpr * E)6600b57cec5SDimitry Andric Value *VisitCXXNewExpr(const CXXNewExpr *E) {
6610b57cec5SDimitry Andric return CGF.EmitCXXNewExpr(E);
6620b57cec5SDimitry Andric }
VisitCXXDeleteExpr(const CXXDeleteExpr * E)6630b57cec5SDimitry Andric Value *VisitCXXDeleteExpr(const CXXDeleteExpr *E) {
6640b57cec5SDimitry Andric CGF.EmitCXXDeleteExpr(E);
6650b57cec5SDimitry Andric return nullptr;
6660b57cec5SDimitry Andric }
6670b57cec5SDimitry Andric
VisitTypeTraitExpr(const TypeTraitExpr * E)6680b57cec5SDimitry Andric Value *VisitTypeTraitExpr(const TypeTraitExpr *E) {
6690b57cec5SDimitry Andric return llvm::ConstantInt::get(ConvertType(E->getType()), E->getValue());
6700b57cec5SDimitry Andric }
6710b57cec5SDimitry Andric
VisitConceptSpecializationExpr(const ConceptSpecializationExpr * E)672a7dea167SDimitry Andric Value *VisitConceptSpecializationExpr(const ConceptSpecializationExpr *E) {
673a7dea167SDimitry Andric return Builder.getInt1(E->isSatisfied());
674a7dea167SDimitry Andric }
675a7dea167SDimitry Andric
VisitRequiresExpr(const RequiresExpr * E)67655e4f9d5SDimitry Andric Value *VisitRequiresExpr(const RequiresExpr *E) {
67755e4f9d5SDimitry Andric return Builder.getInt1(E->isSatisfied());
67855e4f9d5SDimitry Andric }
67955e4f9d5SDimitry Andric
VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr * E)6800b57cec5SDimitry Andric Value *VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E) {
6810b57cec5SDimitry Andric return llvm::ConstantInt::get(Builder.getInt32Ty(), E->getValue());
6820b57cec5SDimitry Andric }
6830b57cec5SDimitry Andric
VisitExpressionTraitExpr(const ExpressionTraitExpr * E)6840b57cec5SDimitry Andric Value *VisitExpressionTraitExpr(const ExpressionTraitExpr *E) {
6850b57cec5SDimitry Andric return llvm::ConstantInt::get(Builder.getInt1Ty(), E->getValue());
6860b57cec5SDimitry Andric }
6870b57cec5SDimitry Andric
VisitCXXPseudoDestructorExpr(const CXXPseudoDestructorExpr * E)6880b57cec5SDimitry Andric Value *VisitCXXPseudoDestructorExpr(const CXXPseudoDestructorExpr *E) {
6890b57cec5SDimitry Andric // C++ [expr.pseudo]p1:
6900b57cec5SDimitry Andric // The result shall only be used as the operand for the function call
6910b57cec5SDimitry Andric // operator (), and the result of such a call has type void. The only
6920b57cec5SDimitry Andric // effect is the evaluation of the postfix-expression before the dot or
6930b57cec5SDimitry Andric // arrow.
6940b57cec5SDimitry Andric CGF.EmitScalarExpr(E->getBase());
6950b57cec5SDimitry Andric return nullptr;
6960b57cec5SDimitry Andric }
6970b57cec5SDimitry Andric
VisitCXXNullPtrLiteralExpr(const CXXNullPtrLiteralExpr * E)6980b57cec5SDimitry Andric Value *VisitCXXNullPtrLiteralExpr(const CXXNullPtrLiteralExpr *E) {
6990b57cec5SDimitry Andric return EmitNullValue(E->getType());
7000b57cec5SDimitry Andric }
7010b57cec5SDimitry Andric
VisitCXXThrowExpr(const CXXThrowExpr * E)7020b57cec5SDimitry Andric Value *VisitCXXThrowExpr(const CXXThrowExpr *E) {
7030b57cec5SDimitry Andric CGF.EmitCXXThrowExpr(E);
7040b57cec5SDimitry Andric return nullptr;
7050b57cec5SDimitry Andric }
7060b57cec5SDimitry Andric
VisitCXXNoexceptExpr(const CXXNoexceptExpr * E)7070b57cec5SDimitry Andric Value *VisitCXXNoexceptExpr(const CXXNoexceptExpr *E) {
7080b57cec5SDimitry Andric return Builder.getInt1(E->getValue());
7090b57cec5SDimitry Andric }
7100b57cec5SDimitry Andric
7110b57cec5SDimitry Andric // Binary Operators.
EmitMul(const BinOpInfo & Ops)7120b57cec5SDimitry Andric Value *EmitMul(const BinOpInfo &Ops) {
7130b57cec5SDimitry Andric if (Ops.Ty->isSignedIntegerOrEnumerationType()) {
7140b57cec5SDimitry Andric switch (CGF.getLangOpts().getSignedOverflowBehavior()) {
7150b57cec5SDimitry Andric case LangOptions::SOB_Defined:
7160b57cec5SDimitry Andric return Builder.CreateMul(Ops.LHS, Ops.RHS, "mul");
7170b57cec5SDimitry Andric case LangOptions::SOB_Undefined:
7180b57cec5SDimitry Andric if (!CGF.SanOpts.has(SanitizerKind::SignedIntegerOverflow))
7190b57cec5SDimitry Andric return Builder.CreateNSWMul(Ops.LHS, Ops.RHS, "mul");
7200b57cec5SDimitry Andric LLVM_FALLTHROUGH;
7210b57cec5SDimitry Andric case LangOptions::SOB_Trapping:
7220b57cec5SDimitry Andric if (CanElideOverflowCheck(CGF.getContext(), Ops))
7230b57cec5SDimitry Andric return Builder.CreateNSWMul(Ops.LHS, Ops.RHS, "mul");
7240b57cec5SDimitry Andric return EmitOverflowCheckedBinOp(Ops);
7250b57cec5SDimitry Andric }
7260b57cec5SDimitry Andric }
7270b57cec5SDimitry Andric
7285ffd83dbSDimitry Andric if (Ops.Ty->isConstantMatrixType()) {
7295ffd83dbSDimitry Andric llvm::MatrixBuilder<CGBuilderTy> MB(Builder);
7305ffd83dbSDimitry Andric // We need to check the types of the operands of the operator to get the
7315ffd83dbSDimitry Andric // correct matrix dimensions.
7325ffd83dbSDimitry Andric auto *BO = cast<BinaryOperator>(Ops.E);
7335ffd83dbSDimitry Andric auto *LHSMatTy = dyn_cast<ConstantMatrixType>(
7345ffd83dbSDimitry Andric BO->getLHS()->getType().getCanonicalType());
7355ffd83dbSDimitry Andric auto *RHSMatTy = dyn_cast<ConstantMatrixType>(
7365ffd83dbSDimitry Andric BO->getRHS()->getType().getCanonicalType());
737*5f7ddb14SDimitry Andric CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, Ops.FPFeatures);
7385ffd83dbSDimitry Andric if (LHSMatTy && RHSMatTy)
7395ffd83dbSDimitry Andric return MB.CreateMatrixMultiply(Ops.LHS, Ops.RHS, LHSMatTy->getNumRows(),
7405ffd83dbSDimitry Andric LHSMatTy->getNumColumns(),
7415ffd83dbSDimitry Andric RHSMatTy->getNumColumns());
7425ffd83dbSDimitry Andric return MB.CreateScalarMultiply(Ops.LHS, Ops.RHS);
7435ffd83dbSDimitry Andric }
7445ffd83dbSDimitry Andric
7450b57cec5SDimitry Andric if (Ops.Ty->isUnsignedIntegerType() &&
7460b57cec5SDimitry Andric CGF.SanOpts.has(SanitizerKind::UnsignedIntegerOverflow) &&
7470b57cec5SDimitry Andric !CanElideOverflowCheck(CGF.getContext(), Ops))
7480b57cec5SDimitry Andric return EmitOverflowCheckedBinOp(Ops);
7490b57cec5SDimitry Andric
7500b57cec5SDimitry Andric if (Ops.LHS->getType()->isFPOrFPVectorTy()) {
7515ffd83dbSDimitry Andric // Preserve the old values
7525ffd83dbSDimitry Andric CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, Ops.FPFeatures);
7535ffd83dbSDimitry Andric return Builder.CreateFMul(Ops.LHS, Ops.RHS, "mul");
7540b57cec5SDimitry Andric }
7555ffd83dbSDimitry Andric if (Ops.isFixedPointOp())
7565ffd83dbSDimitry Andric return EmitFixedPointBinOp(Ops);
7570b57cec5SDimitry Andric return Builder.CreateMul(Ops.LHS, Ops.RHS, "mul");
7580b57cec5SDimitry Andric }
7590b57cec5SDimitry Andric /// Create a binary op that checks for overflow.
7600b57cec5SDimitry Andric /// Currently only supports +, - and *.
7610b57cec5SDimitry Andric Value *EmitOverflowCheckedBinOp(const BinOpInfo &Ops);
7620b57cec5SDimitry Andric
7630b57cec5SDimitry Andric // Check for undefined division and modulus behaviors.
7640b57cec5SDimitry Andric void EmitUndefinedBehaviorIntegerDivAndRemCheck(const BinOpInfo &Ops,
7650b57cec5SDimitry Andric llvm::Value *Zero,bool isDiv);
7660b57cec5SDimitry Andric // Common helper for getting how wide LHS of shift is.
7670b57cec5SDimitry Andric static Value *GetWidthMinusOneValue(Value* LHS,Value* RHS);
7685ffd83dbSDimitry Andric
7695ffd83dbSDimitry Andric // Used for shifting constraints for OpenCL, do mask for powers of 2, URem for
7705ffd83dbSDimitry Andric // non powers of two.
7715ffd83dbSDimitry Andric Value *ConstrainShiftValue(Value *LHS, Value *RHS, const Twine &Name);
7725ffd83dbSDimitry Andric
7730b57cec5SDimitry Andric Value *EmitDiv(const BinOpInfo &Ops);
7740b57cec5SDimitry Andric Value *EmitRem(const BinOpInfo &Ops);
7750b57cec5SDimitry Andric Value *EmitAdd(const BinOpInfo &Ops);
7760b57cec5SDimitry Andric Value *EmitSub(const BinOpInfo &Ops);
7770b57cec5SDimitry Andric Value *EmitShl(const BinOpInfo &Ops);
7780b57cec5SDimitry Andric Value *EmitShr(const BinOpInfo &Ops);
EmitAnd(const BinOpInfo & Ops)7790b57cec5SDimitry Andric Value *EmitAnd(const BinOpInfo &Ops) {
7800b57cec5SDimitry Andric return Builder.CreateAnd(Ops.LHS, Ops.RHS, "and");
7810b57cec5SDimitry Andric }
EmitXor(const BinOpInfo & Ops)7820b57cec5SDimitry Andric Value *EmitXor(const BinOpInfo &Ops) {
7830b57cec5SDimitry Andric return Builder.CreateXor(Ops.LHS, Ops.RHS, "xor");
7840b57cec5SDimitry Andric }
EmitOr(const BinOpInfo & Ops)7850b57cec5SDimitry Andric Value *EmitOr (const BinOpInfo &Ops) {
7860b57cec5SDimitry Andric return Builder.CreateOr(Ops.LHS, Ops.RHS, "or");
7870b57cec5SDimitry Andric }
7880b57cec5SDimitry Andric
7890b57cec5SDimitry Andric // Helper functions for fixed point binary operations.
7900b57cec5SDimitry Andric Value *EmitFixedPointBinOp(const BinOpInfo &Ops);
7910b57cec5SDimitry Andric
7920b57cec5SDimitry Andric BinOpInfo EmitBinOps(const BinaryOperator *E);
7930b57cec5SDimitry Andric LValue EmitCompoundAssignLValue(const CompoundAssignOperator *E,
7940b57cec5SDimitry Andric Value *(ScalarExprEmitter::*F)(const BinOpInfo &),
7950b57cec5SDimitry Andric Value *&Result);
7960b57cec5SDimitry Andric
7970b57cec5SDimitry Andric Value *EmitCompoundAssign(const CompoundAssignOperator *E,
7980b57cec5SDimitry Andric Value *(ScalarExprEmitter::*F)(const BinOpInfo &));
7990b57cec5SDimitry Andric
8000b57cec5SDimitry Andric // Binary operators and binary compound assignment operators.
8010b57cec5SDimitry Andric #define HANDLEBINOP(OP) \
8020b57cec5SDimitry Andric Value *VisitBin ## OP(const BinaryOperator *E) { \
8030b57cec5SDimitry Andric return Emit ## OP(EmitBinOps(E)); \
8040b57cec5SDimitry Andric } \
8050b57cec5SDimitry Andric Value *VisitBin ## OP ## Assign(const CompoundAssignOperator *E) { \
8060b57cec5SDimitry Andric return EmitCompoundAssign(E, &ScalarExprEmitter::Emit ## OP); \
8070b57cec5SDimitry Andric }
8080b57cec5SDimitry Andric HANDLEBINOP(Mul)
8090b57cec5SDimitry Andric HANDLEBINOP(Div)
8100b57cec5SDimitry Andric HANDLEBINOP(Rem)
8110b57cec5SDimitry Andric HANDLEBINOP(Add)
8120b57cec5SDimitry Andric HANDLEBINOP(Sub)
8130b57cec5SDimitry Andric HANDLEBINOP(Shl)
8140b57cec5SDimitry Andric HANDLEBINOP(Shr)
8150b57cec5SDimitry Andric HANDLEBINOP(And)
8160b57cec5SDimitry Andric HANDLEBINOP(Xor)
8170b57cec5SDimitry Andric HANDLEBINOP(Or)
8180b57cec5SDimitry Andric #undef HANDLEBINOP
8190b57cec5SDimitry Andric
8200b57cec5SDimitry Andric // Comparisons.
8210b57cec5SDimitry Andric Value *EmitCompare(const BinaryOperator *E, llvm::CmpInst::Predicate UICmpOpc,
8220b57cec5SDimitry Andric llvm::CmpInst::Predicate SICmpOpc,
823480093f4SDimitry Andric llvm::CmpInst::Predicate FCmpOpc, bool IsSignaling);
824480093f4SDimitry Andric #define VISITCOMP(CODE, UI, SI, FP, SIG) \
8250b57cec5SDimitry Andric Value *VisitBin##CODE(const BinaryOperator *E) { \
8260b57cec5SDimitry Andric return EmitCompare(E, llvm::ICmpInst::UI, llvm::ICmpInst::SI, \
827480093f4SDimitry Andric llvm::FCmpInst::FP, SIG); }
828480093f4SDimitry Andric VISITCOMP(LT, ICMP_ULT, ICMP_SLT, FCMP_OLT, true)
829480093f4SDimitry Andric VISITCOMP(GT, ICMP_UGT, ICMP_SGT, FCMP_OGT, true)
830480093f4SDimitry Andric VISITCOMP(LE, ICMP_ULE, ICMP_SLE, FCMP_OLE, true)
831480093f4SDimitry Andric VISITCOMP(GE, ICMP_UGE, ICMP_SGE, FCMP_OGE, true)
832480093f4SDimitry Andric VISITCOMP(EQ, ICMP_EQ , ICMP_EQ , FCMP_OEQ, false)
833480093f4SDimitry Andric VISITCOMP(NE, ICMP_NE , ICMP_NE , FCMP_UNE, false)
8340b57cec5SDimitry Andric #undef VISITCOMP
8350b57cec5SDimitry Andric
8360b57cec5SDimitry Andric Value *VisitBinAssign (const BinaryOperator *E);
8370b57cec5SDimitry Andric
8380b57cec5SDimitry Andric Value *VisitBinLAnd (const BinaryOperator *E);
8390b57cec5SDimitry Andric Value *VisitBinLOr (const BinaryOperator *E);
8400b57cec5SDimitry Andric Value *VisitBinComma (const BinaryOperator *E);
8410b57cec5SDimitry Andric
VisitBinPtrMemD(const Expr * E)8420b57cec5SDimitry Andric Value *VisitBinPtrMemD(const Expr *E) { return EmitLoadOfLValue(E); }
VisitBinPtrMemI(const Expr * E)8430b57cec5SDimitry Andric Value *VisitBinPtrMemI(const Expr *E) { return EmitLoadOfLValue(E); }
8440b57cec5SDimitry Andric
VisitCXXRewrittenBinaryOperator(CXXRewrittenBinaryOperator * E)845a7dea167SDimitry Andric Value *VisitCXXRewrittenBinaryOperator(CXXRewrittenBinaryOperator *E) {
846a7dea167SDimitry Andric return Visit(E->getSemanticForm());
847a7dea167SDimitry Andric }
848a7dea167SDimitry Andric
8490b57cec5SDimitry Andric // Other Operators.
8500b57cec5SDimitry Andric Value *VisitBlockExpr(const BlockExpr *BE);
8510b57cec5SDimitry Andric Value *VisitAbstractConditionalOperator(const AbstractConditionalOperator *);
8520b57cec5SDimitry Andric Value *VisitChooseExpr(ChooseExpr *CE);
8530b57cec5SDimitry Andric Value *VisitVAArgExpr(VAArgExpr *VE);
VisitObjCStringLiteral(const ObjCStringLiteral * E)8540b57cec5SDimitry Andric Value *VisitObjCStringLiteral(const ObjCStringLiteral *E) {
8550b57cec5SDimitry Andric return CGF.EmitObjCStringLiteral(E);
8560b57cec5SDimitry Andric }
VisitObjCBoxedExpr(ObjCBoxedExpr * E)8570b57cec5SDimitry Andric Value *VisitObjCBoxedExpr(ObjCBoxedExpr *E) {
8580b57cec5SDimitry Andric return CGF.EmitObjCBoxedExpr(E);
8590b57cec5SDimitry Andric }
VisitObjCArrayLiteral(ObjCArrayLiteral * E)8600b57cec5SDimitry Andric Value *VisitObjCArrayLiteral(ObjCArrayLiteral *E) {
8610b57cec5SDimitry Andric return CGF.EmitObjCArrayLiteral(E);
8620b57cec5SDimitry Andric }
VisitObjCDictionaryLiteral(ObjCDictionaryLiteral * E)8630b57cec5SDimitry Andric Value *VisitObjCDictionaryLiteral(ObjCDictionaryLiteral *E) {
8640b57cec5SDimitry Andric return CGF.EmitObjCDictionaryLiteral(E);
8650b57cec5SDimitry Andric }
8660b57cec5SDimitry Andric Value *VisitAsTypeExpr(AsTypeExpr *CE);
8670b57cec5SDimitry Andric Value *VisitAtomicExpr(AtomicExpr *AE);
8680b57cec5SDimitry Andric };
8690b57cec5SDimitry Andric } // end anonymous namespace.
8700b57cec5SDimitry Andric
8710b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
8720b57cec5SDimitry Andric // Utilities
8730b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
8740b57cec5SDimitry Andric
8750b57cec5SDimitry Andric /// EmitConversionToBool - Convert the specified expression value to a
8760b57cec5SDimitry Andric /// boolean (i1) truth value. This is equivalent to "Val != 0".
EmitConversionToBool(Value * Src,QualType SrcType)8770b57cec5SDimitry Andric Value *ScalarExprEmitter::EmitConversionToBool(Value *Src, QualType SrcType) {
8780b57cec5SDimitry Andric assert(SrcType.isCanonical() && "EmitScalarConversion strips typedefs");
8790b57cec5SDimitry Andric
8800b57cec5SDimitry Andric if (SrcType->isRealFloatingType())
8810b57cec5SDimitry Andric return EmitFloatToBoolConversion(Src);
8820b57cec5SDimitry Andric
8830b57cec5SDimitry Andric if (const MemberPointerType *MPT = dyn_cast<MemberPointerType>(SrcType))
8840b57cec5SDimitry Andric return CGF.CGM.getCXXABI().EmitMemberPointerIsNotNull(CGF, Src, MPT);
8850b57cec5SDimitry Andric
8860b57cec5SDimitry Andric assert((SrcType->isIntegerType() || isa<llvm::PointerType>(Src->getType())) &&
8870b57cec5SDimitry Andric "Unknown scalar type to convert");
8880b57cec5SDimitry Andric
8890b57cec5SDimitry Andric if (isa<llvm::IntegerType>(Src->getType()))
8900b57cec5SDimitry Andric return EmitIntToBoolConversion(Src);
8910b57cec5SDimitry Andric
8920b57cec5SDimitry Andric assert(isa<llvm::PointerType>(Src->getType()));
8930b57cec5SDimitry Andric return EmitPointerToBoolConversion(Src, SrcType);
8940b57cec5SDimitry Andric }
8950b57cec5SDimitry Andric
EmitFloatConversionCheck(Value * OrigSrc,QualType OrigSrcType,Value * Src,QualType SrcType,QualType DstType,llvm::Type * DstTy,SourceLocation Loc)8960b57cec5SDimitry Andric void ScalarExprEmitter::EmitFloatConversionCheck(
8970b57cec5SDimitry Andric Value *OrigSrc, QualType OrigSrcType, Value *Src, QualType SrcType,
8980b57cec5SDimitry Andric QualType DstType, llvm::Type *DstTy, SourceLocation Loc) {
8990b57cec5SDimitry Andric assert(SrcType->isFloatingType() && "not a conversion from floating point");
9000b57cec5SDimitry Andric if (!isa<llvm::IntegerType>(DstTy))
9010b57cec5SDimitry Andric return;
9020b57cec5SDimitry Andric
9030b57cec5SDimitry Andric CodeGenFunction::SanitizerScope SanScope(&CGF);
9040b57cec5SDimitry Andric using llvm::APFloat;
9050b57cec5SDimitry Andric using llvm::APSInt;
9060b57cec5SDimitry Andric
9070b57cec5SDimitry Andric llvm::Value *Check = nullptr;
9080b57cec5SDimitry Andric const llvm::fltSemantics &SrcSema =
9090b57cec5SDimitry Andric CGF.getContext().getFloatTypeSemantics(OrigSrcType);
9100b57cec5SDimitry Andric
9110b57cec5SDimitry Andric // Floating-point to integer. This has undefined behavior if the source is
9120b57cec5SDimitry Andric // +-Inf, NaN, or doesn't fit into the destination type (after truncation
9130b57cec5SDimitry Andric // to an integer).
9140b57cec5SDimitry Andric unsigned Width = CGF.getContext().getIntWidth(DstType);
9150b57cec5SDimitry Andric bool Unsigned = DstType->isUnsignedIntegerOrEnumerationType();
9160b57cec5SDimitry Andric
9170b57cec5SDimitry Andric APSInt Min = APSInt::getMinValue(Width, Unsigned);
9180b57cec5SDimitry Andric APFloat MinSrc(SrcSema, APFloat::uninitialized);
9190b57cec5SDimitry Andric if (MinSrc.convertFromAPInt(Min, !Unsigned, APFloat::rmTowardZero) &
9200b57cec5SDimitry Andric APFloat::opOverflow)
9210b57cec5SDimitry Andric // Don't need an overflow check for lower bound. Just check for
9220b57cec5SDimitry Andric // -Inf/NaN.
9230b57cec5SDimitry Andric MinSrc = APFloat::getInf(SrcSema, true);
9240b57cec5SDimitry Andric else
9250b57cec5SDimitry Andric // Find the largest value which is too small to represent (before
9260b57cec5SDimitry Andric // truncation toward zero).
9270b57cec5SDimitry Andric MinSrc.subtract(APFloat(SrcSema, 1), APFloat::rmTowardNegative);
9280b57cec5SDimitry Andric
9290b57cec5SDimitry Andric APSInt Max = APSInt::getMaxValue(Width, Unsigned);
9300b57cec5SDimitry Andric APFloat MaxSrc(SrcSema, APFloat::uninitialized);
9310b57cec5SDimitry Andric if (MaxSrc.convertFromAPInt(Max, !Unsigned, APFloat::rmTowardZero) &
9320b57cec5SDimitry Andric APFloat::opOverflow)
9330b57cec5SDimitry Andric // Don't need an overflow check for upper bound. Just check for
9340b57cec5SDimitry Andric // +Inf/NaN.
9350b57cec5SDimitry Andric MaxSrc = APFloat::getInf(SrcSema, false);
9360b57cec5SDimitry Andric else
9370b57cec5SDimitry Andric // Find the smallest value which is too large to represent (before
9380b57cec5SDimitry Andric // truncation toward zero).
9390b57cec5SDimitry Andric MaxSrc.add(APFloat(SrcSema, 1), APFloat::rmTowardPositive);
9400b57cec5SDimitry Andric
9410b57cec5SDimitry Andric // If we're converting from __half, convert the range to float to match
9420b57cec5SDimitry Andric // the type of src.
9430b57cec5SDimitry Andric if (OrigSrcType->isHalfType()) {
9440b57cec5SDimitry Andric const llvm::fltSemantics &Sema =
9450b57cec5SDimitry Andric CGF.getContext().getFloatTypeSemantics(SrcType);
9460b57cec5SDimitry Andric bool IsInexact;
9470b57cec5SDimitry Andric MinSrc.convert(Sema, APFloat::rmTowardZero, &IsInexact);
9480b57cec5SDimitry Andric MaxSrc.convert(Sema, APFloat::rmTowardZero, &IsInexact);
9490b57cec5SDimitry Andric }
9500b57cec5SDimitry Andric
9510b57cec5SDimitry Andric llvm::Value *GE =
9520b57cec5SDimitry Andric Builder.CreateFCmpOGT(Src, llvm::ConstantFP::get(VMContext, MinSrc));
9530b57cec5SDimitry Andric llvm::Value *LE =
9540b57cec5SDimitry Andric Builder.CreateFCmpOLT(Src, llvm::ConstantFP::get(VMContext, MaxSrc));
9550b57cec5SDimitry Andric Check = Builder.CreateAnd(GE, LE);
9560b57cec5SDimitry Andric
9570b57cec5SDimitry Andric llvm::Constant *StaticArgs[] = {CGF.EmitCheckSourceLocation(Loc),
9580b57cec5SDimitry Andric CGF.EmitCheckTypeDescriptor(OrigSrcType),
9590b57cec5SDimitry Andric CGF.EmitCheckTypeDescriptor(DstType)};
9600b57cec5SDimitry Andric CGF.EmitCheck(std::make_pair(Check, SanitizerKind::FloatCastOverflow),
9610b57cec5SDimitry Andric SanitizerHandler::FloatCastOverflow, StaticArgs, OrigSrc);
9620b57cec5SDimitry Andric }
9630b57cec5SDimitry Andric
9640b57cec5SDimitry Andric // Should be called within CodeGenFunction::SanitizerScope RAII scope.
9650b57cec5SDimitry Andric // Returns 'i1 false' when the truncation Src -> Dst was lossy.
9660b57cec5SDimitry Andric static std::pair<ScalarExprEmitter::ImplicitConversionCheckKind,
9670b57cec5SDimitry Andric std::pair<llvm::Value *, SanitizerMask>>
EmitIntegerTruncationCheckHelper(Value * Src,QualType SrcType,Value * Dst,QualType DstType,CGBuilderTy & Builder)9680b57cec5SDimitry Andric EmitIntegerTruncationCheckHelper(Value *Src, QualType SrcType, Value *Dst,
9690b57cec5SDimitry Andric QualType DstType, CGBuilderTy &Builder) {
9700b57cec5SDimitry Andric llvm::Type *SrcTy = Src->getType();
9710b57cec5SDimitry Andric llvm::Type *DstTy = Dst->getType();
9720b57cec5SDimitry Andric (void)DstTy; // Only used in assert()
9730b57cec5SDimitry Andric
9740b57cec5SDimitry Andric // This should be truncation of integral types.
9750b57cec5SDimitry Andric assert(Src != Dst);
9760b57cec5SDimitry Andric assert(SrcTy->getScalarSizeInBits() > Dst->getType()->getScalarSizeInBits());
9770b57cec5SDimitry Andric assert(isa<llvm::IntegerType>(SrcTy) && isa<llvm::IntegerType>(DstTy) &&
9780b57cec5SDimitry Andric "non-integer llvm type");
9790b57cec5SDimitry Andric
9800b57cec5SDimitry Andric bool SrcSigned = SrcType->isSignedIntegerOrEnumerationType();
9810b57cec5SDimitry Andric bool DstSigned = DstType->isSignedIntegerOrEnumerationType();
9820b57cec5SDimitry Andric
9830b57cec5SDimitry Andric // If both (src and dst) types are unsigned, then it's an unsigned truncation.
9840b57cec5SDimitry Andric // Else, it is a signed truncation.
9850b57cec5SDimitry Andric ScalarExprEmitter::ImplicitConversionCheckKind Kind;
9860b57cec5SDimitry Andric SanitizerMask Mask;
9870b57cec5SDimitry Andric if (!SrcSigned && !DstSigned) {
9880b57cec5SDimitry Andric Kind = ScalarExprEmitter::ICCK_UnsignedIntegerTruncation;
9890b57cec5SDimitry Andric Mask = SanitizerKind::ImplicitUnsignedIntegerTruncation;
9900b57cec5SDimitry Andric } else {
9910b57cec5SDimitry Andric Kind = ScalarExprEmitter::ICCK_SignedIntegerTruncation;
9920b57cec5SDimitry Andric Mask = SanitizerKind::ImplicitSignedIntegerTruncation;
9930b57cec5SDimitry Andric }
9940b57cec5SDimitry Andric
9950b57cec5SDimitry Andric llvm::Value *Check = nullptr;
9960b57cec5SDimitry Andric // 1. Extend the truncated value back to the same width as the Src.
9970b57cec5SDimitry Andric Check = Builder.CreateIntCast(Dst, SrcTy, DstSigned, "anyext");
9980b57cec5SDimitry Andric // 2. Equality-compare with the original source value
9990b57cec5SDimitry Andric Check = Builder.CreateICmpEQ(Check, Src, "truncheck");
10000b57cec5SDimitry Andric // If the comparison result is 'i1 false', then the truncation was lossy.
10010b57cec5SDimitry Andric return std::make_pair(Kind, std::make_pair(Check, Mask));
10020b57cec5SDimitry Andric }
10030b57cec5SDimitry Andric
PromotionIsPotentiallyEligibleForImplicitIntegerConversionCheck(QualType SrcType,QualType DstType)1004480093f4SDimitry Andric static bool PromotionIsPotentiallyEligibleForImplicitIntegerConversionCheck(
1005480093f4SDimitry Andric QualType SrcType, QualType DstType) {
1006480093f4SDimitry Andric return SrcType->isIntegerType() && DstType->isIntegerType();
1007480093f4SDimitry Andric }
1008480093f4SDimitry Andric
EmitIntegerTruncationCheck(Value * Src,QualType SrcType,Value * Dst,QualType DstType,SourceLocation Loc)10090b57cec5SDimitry Andric void ScalarExprEmitter::EmitIntegerTruncationCheck(Value *Src, QualType SrcType,
10100b57cec5SDimitry Andric Value *Dst, QualType DstType,
10110b57cec5SDimitry Andric SourceLocation Loc) {
10120b57cec5SDimitry Andric if (!CGF.SanOpts.hasOneOf(SanitizerKind::ImplicitIntegerTruncation))
10130b57cec5SDimitry Andric return;
10140b57cec5SDimitry Andric
10150b57cec5SDimitry Andric // We only care about int->int conversions here.
10160b57cec5SDimitry Andric // We ignore conversions to/from pointer and/or bool.
1017480093f4SDimitry Andric if (!PromotionIsPotentiallyEligibleForImplicitIntegerConversionCheck(SrcType,
1018480093f4SDimitry Andric DstType))
10190b57cec5SDimitry Andric return;
10200b57cec5SDimitry Andric
10210b57cec5SDimitry Andric unsigned SrcBits = Src->getType()->getScalarSizeInBits();
10220b57cec5SDimitry Andric unsigned DstBits = Dst->getType()->getScalarSizeInBits();
10230b57cec5SDimitry Andric // This must be truncation. Else we do not care.
10240b57cec5SDimitry Andric if (SrcBits <= DstBits)
10250b57cec5SDimitry Andric return;
10260b57cec5SDimitry Andric
10270b57cec5SDimitry Andric assert(!DstType->isBooleanType() && "we should not get here with booleans.");
10280b57cec5SDimitry Andric
10290b57cec5SDimitry Andric // If the integer sign change sanitizer is enabled,
10300b57cec5SDimitry Andric // and we are truncating from larger unsigned type to smaller signed type,
10310b57cec5SDimitry Andric // let that next sanitizer deal with it.
10320b57cec5SDimitry Andric bool SrcSigned = SrcType->isSignedIntegerOrEnumerationType();
10330b57cec5SDimitry Andric bool DstSigned = DstType->isSignedIntegerOrEnumerationType();
10340b57cec5SDimitry Andric if (CGF.SanOpts.has(SanitizerKind::ImplicitIntegerSignChange) &&
10350b57cec5SDimitry Andric (!SrcSigned && DstSigned))
10360b57cec5SDimitry Andric return;
10370b57cec5SDimitry Andric
10380b57cec5SDimitry Andric CodeGenFunction::SanitizerScope SanScope(&CGF);
10390b57cec5SDimitry Andric
10400b57cec5SDimitry Andric std::pair<ScalarExprEmitter::ImplicitConversionCheckKind,
10410b57cec5SDimitry Andric std::pair<llvm::Value *, SanitizerMask>>
10420b57cec5SDimitry Andric Check =
10430b57cec5SDimitry Andric EmitIntegerTruncationCheckHelper(Src, SrcType, Dst, DstType, Builder);
10440b57cec5SDimitry Andric // If the comparison result is 'i1 false', then the truncation was lossy.
10450b57cec5SDimitry Andric
10460b57cec5SDimitry Andric // Do we care about this type of truncation?
10470b57cec5SDimitry Andric if (!CGF.SanOpts.has(Check.second.second))
10480b57cec5SDimitry Andric return;
10490b57cec5SDimitry Andric
10500b57cec5SDimitry Andric llvm::Constant *StaticArgs[] = {
10510b57cec5SDimitry Andric CGF.EmitCheckSourceLocation(Loc), CGF.EmitCheckTypeDescriptor(SrcType),
10520b57cec5SDimitry Andric CGF.EmitCheckTypeDescriptor(DstType),
10530b57cec5SDimitry Andric llvm::ConstantInt::get(Builder.getInt8Ty(), Check.first)};
10540b57cec5SDimitry Andric CGF.EmitCheck(Check.second, SanitizerHandler::ImplicitConversion, StaticArgs,
10550b57cec5SDimitry Andric {Src, Dst});
10560b57cec5SDimitry Andric }
10570b57cec5SDimitry Andric
10580b57cec5SDimitry Andric // Should be called within CodeGenFunction::SanitizerScope RAII scope.
10590b57cec5SDimitry Andric // Returns 'i1 false' when the conversion Src -> Dst changed the sign.
10600b57cec5SDimitry Andric static std::pair<ScalarExprEmitter::ImplicitConversionCheckKind,
10610b57cec5SDimitry Andric std::pair<llvm::Value *, SanitizerMask>>
EmitIntegerSignChangeCheckHelper(Value * Src,QualType SrcType,Value * Dst,QualType DstType,CGBuilderTy & Builder)10620b57cec5SDimitry Andric EmitIntegerSignChangeCheckHelper(Value *Src, QualType SrcType, Value *Dst,
10630b57cec5SDimitry Andric QualType DstType, CGBuilderTy &Builder) {
10640b57cec5SDimitry Andric llvm::Type *SrcTy = Src->getType();
10650b57cec5SDimitry Andric llvm::Type *DstTy = Dst->getType();
10660b57cec5SDimitry Andric
10670b57cec5SDimitry Andric assert(isa<llvm::IntegerType>(SrcTy) && isa<llvm::IntegerType>(DstTy) &&
10680b57cec5SDimitry Andric "non-integer llvm type");
10690b57cec5SDimitry Andric
10700b57cec5SDimitry Andric bool SrcSigned = SrcType->isSignedIntegerOrEnumerationType();
10710b57cec5SDimitry Andric bool DstSigned = DstType->isSignedIntegerOrEnumerationType();
10720b57cec5SDimitry Andric (void)SrcSigned; // Only used in assert()
10730b57cec5SDimitry Andric (void)DstSigned; // Only used in assert()
10740b57cec5SDimitry Andric unsigned SrcBits = SrcTy->getScalarSizeInBits();
10750b57cec5SDimitry Andric unsigned DstBits = DstTy->getScalarSizeInBits();
10760b57cec5SDimitry Andric (void)SrcBits; // Only used in assert()
10770b57cec5SDimitry Andric (void)DstBits; // Only used in assert()
10780b57cec5SDimitry Andric
10790b57cec5SDimitry Andric assert(((SrcBits != DstBits) || (SrcSigned != DstSigned)) &&
10800b57cec5SDimitry Andric "either the widths should be different, or the signednesses.");
10810b57cec5SDimitry Andric
10820b57cec5SDimitry Andric // NOTE: zero value is considered to be non-negative.
10830b57cec5SDimitry Andric auto EmitIsNegativeTest = [&Builder](Value *V, QualType VType,
10840b57cec5SDimitry Andric const char *Name) -> Value * {
10850b57cec5SDimitry Andric // Is this value a signed type?
10860b57cec5SDimitry Andric bool VSigned = VType->isSignedIntegerOrEnumerationType();
10870b57cec5SDimitry Andric llvm::Type *VTy = V->getType();
10880b57cec5SDimitry Andric if (!VSigned) {
10890b57cec5SDimitry Andric // If the value is unsigned, then it is never negative.
10900b57cec5SDimitry Andric // FIXME: can we encounter non-scalar VTy here?
10910b57cec5SDimitry Andric return llvm::ConstantInt::getFalse(VTy->getContext());
10920b57cec5SDimitry Andric }
10930b57cec5SDimitry Andric // Get the zero of the same type with which we will be comparing.
10940b57cec5SDimitry Andric llvm::Constant *Zero = llvm::ConstantInt::get(VTy, 0);
10950b57cec5SDimitry Andric // %V.isnegative = icmp slt %V, 0
10960b57cec5SDimitry Andric // I.e is %V *strictly* less than zero, does it have negative value?
10970b57cec5SDimitry Andric return Builder.CreateICmp(llvm::ICmpInst::ICMP_SLT, V, Zero,
10980b57cec5SDimitry Andric llvm::Twine(Name) + "." + V->getName() +
10990b57cec5SDimitry Andric ".negativitycheck");
11000b57cec5SDimitry Andric };
11010b57cec5SDimitry Andric
11020b57cec5SDimitry Andric // 1. Was the old Value negative?
11030b57cec5SDimitry Andric llvm::Value *SrcIsNegative = EmitIsNegativeTest(Src, SrcType, "src");
11040b57cec5SDimitry Andric // 2. Is the new Value negative?
11050b57cec5SDimitry Andric llvm::Value *DstIsNegative = EmitIsNegativeTest(Dst, DstType, "dst");
11060b57cec5SDimitry Andric // 3. Now, was the 'negativity status' preserved during the conversion?
11070b57cec5SDimitry Andric // NOTE: conversion from negative to zero is considered to change the sign.
11080b57cec5SDimitry Andric // (We want to get 'false' when the conversion changed the sign)
11090b57cec5SDimitry Andric // So we should just equality-compare the negativity statuses.
11100b57cec5SDimitry Andric llvm::Value *Check = nullptr;
11110b57cec5SDimitry Andric Check = Builder.CreateICmpEQ(SrcIsNegative, DstIsNegative, "signchangecheck");
11120b57cec5SDimitry Andric // If the comparison result is 'false', then the conversion changed the sign.
11130b57cec5SDimitry Andric return std::make_pair(
11140b57cec5SDimitry Andric ScalarExprEmitter::ICCK_IntegerSignChange,
11150b57cec5SDimitry Andric std::make_pair(Check, SanitizerKind::ImplicitIntegerSignChange));
11160b57cec5SDimitry Andric }
11170b57cec5SDimitry Andric
EmitIntegerSignChangeCheck(Value * Src,QualType SrcType,Value * Dst,QualType DstType,SourceLocation Loc)11180b57cec5SDimitry Andric void ScalarExprEmitter::EmitIntegerSignChangeCheck(Value *Src, QualType SrcType,
11190b57cec5SDimitry Andric Value *Dst, QualType DstType,
11200b57cec5SDimitry Andric SourceLocation Loc) {
11210b57cec5SDimitry Andric if (!CGF.SanOpts.has(SanitizerKind::ImplicitIntegerSignChange))
11220b57cec5SDimitry Andric return;
11230b57cec5SDimitry Andric
11240b57cec5SDimitry Andric llvm::Type *SrcTy = Src->getType();
11250b57cec5SDimitry Andric llvm::Type *DstTy = Dst->getType();
11260b57cec5SDimitry Andric
11270b57cec5SDimitry Andric // We only care about int->int conversions here.
11280b57cec5SDimitry Andric // We ignore conversions to/from pointer and/or bool.
1129480093f4SDimitry Andric if (!PromotionIsPotentiallyEligibleForImplicitIntegerConversionCheck(SrcType,
1130480093f4SDimitry Andric DstType))
11310b57cec5SDimitry Andric return;
11320b57cec5SDimitry Andric
11330b57cec5SDimitry Andric bool SrcSigned = SrcType->isSignedIntegerOrEnumerationType();
11340b57cec5SDimitry Andric bool DstSigned = DstType->isSignedIntegerOrEnumerationType();
11350b57cec5SDimitry Andric unsigned SrcBits = SrcTy->getScalarSizeInBits();
11360b57cec5SDimitry Andric unsigned DstBits = DstTy->getScalarSizeInBits();
11370b57cec5SDimitry Andric
11380b57cec5SDimitry Andric // Now, we do not need to emit the check in *all* of the cases.
11390b57cec5SDimitry Andric // We can avoid emitting it in some obvious cases where it would have been
11400b57cec5SDimitry Andric // dropped by the opt passes (instcombine) always anyways.
11410b57cec5SDimitry Andric // If it's a cast between effectively the same type, no check.
11420b57cec5SDimitry Andric // NOTE: this is *not* equivalent to checking the canonical types.
11430b57cec5SDimitry Andric if (SrcSigned == DstSigned && SrcBits == DstBits)
11440b57cec5SDimitry Andric return;
11450b57cec5SDimitry Andric // At least one of the values needs to have signed type.
11460b57cec5SDimitry Andric // If both are unsigned, then obviously, neither of them can be negative.
11470b57cec5SDimitry Andric if (!SrcSigned && !DstSigned)
11480b57cec5SDimitry Andric return;
11490b57cec5SDimitry Andric // If the conversion is to *larger* *signed* type, then no check is needed.
11500b57cec5SDimitry Andric // Because either sign-extension happens (so the sign will remain),
11510b57cec5SDimitry Andric // or zero-extension will happen (the sign bit will be zero.)
11520b57cec5SDimitry Andric if ((DstBits > SrcBits) && DstSigned)
11530b57cec5SDimitry Andric return;
11540b57cec5SDimitry Andric if (CGF.SanOpts.has(SanitizerKind::ImplicitSignedIntegerTruncation) &&
11550b57cec5SDimitry Andric (SrcBits > DstBits) && SrcSigned) {
11560b57cec5SDimitry Andric // If the signed integer truncation sanitizer is enabled,
11570b57cec5SDimitry Andric // and this is a truncation from signed type, then no check is needed.
11580b57cec5SDimitry Andric // Because here sign change check is interchangeable with truncation check.
11590b57cec5SDimitry Andric return;
11600b57cec5SDimitry Andric }
11610b57cec5SDimitry Andric // That's it. We can't rule out any more cases with the data we have.
11620b57cec5SDimitry Andric
11630b57cec5SDimitry Andric CodeGenFunction::SanitizerScope SanScope(&CGF);
11640b57cec5SDimitry Andric
11650b57cec5SDimitry Andric std::pair<ScalarExprEmitter::ImplicitConversionCheckKind,
11660b57cec5SDimitry Andric std::pair<llvm::Value *, SanitizerMask>>
11670b57cec5SDimitry Andric Check;
11680b57cec5SDimitry Andric
11690b57cec5SDimitry Andric // Each of these checks needs to return 'false' when an issue was detected.
11700b57cec5SDimitry Andric ImplicitConversionCheckKind CheckKind;
11710b57cec5SDimitry Andric llvm::SmallVector<std::pair<llvm::Value *, SanitizerMask>, 2> Checks;
11720b57cec5SDimitry Andric // So we can 'and' all the checks together, and still get 'false',
11730b57cec5SDimitry Andric // if at least one of the checks detected an issue.
11740b57cec5SDimitry Andric
11750b57cec5SDimitry Andric Check = EmitIntegerSignChangeCheckHelper(Src, SrcType, Dst, DstType, Builder);
11760b57cec5SDimitry Andric CheckKind = Check.first;
11770b57cec5SDimitry Andric Checks.emplace_back(Check.second);
11780b57cec5SDimitry Andric
11790b57cec5SDimitry Andric if (CGF.SanOpts.has(SanitizerKind::ImplicitSignedIntegerTruncation) &&
11800b57cec5SDimitry Andric (SrcBits > DstBits) && !SrcSigned && DstSigned) {
11810b57cec5SDimitry Andric // If the signed integer truncation sanitizer was enabled,
11820b57cec5SDimitry Andric // and we are truncating from larger unsigned type to smaller signed type,
11830b57cec5SDimitry Andric // let's handle the case we skipped in that check.
11840b57cec5SDimitry Andric Check =
11850b57cec5SDimitry Andric EmitIntegerTruncationCheckHelper(Src, SrcType, Dst, DstType, Builder);
11860b57cec5SDimitry Andric CheckKind = ICCK_SignedIntegerTruncationOrSignChange;
11870b57cec5SDimitry Andric Checks.emplace_back(Check.second);
11880b57cec5SDimitry Andric // If the comparison result is 'i1 false', then the truncation was lossy.
11890b57cec5SDimitry Andric }
11900b57cec5SDimitry Andric
11910b57cec5SDimitry Andric llvm::Constant *StaticArgs[] = {
11920b57cec5SDimitry Andric CGF.EmitCheckSourceLocation(Loc), CGF.EmitCheckTypeDescriptor(SrcType),
11930b57cec5SDimitry Andric CGF.EmitCheckTypeDescriptor(DstType),
11940b57cec5SDimitry Andric llvm::ConstantInt::get(Builder.getInt8Ty(), CheckKind)};
11950b57cec5SDimitry Andric // EmitCheck() will 'and' all the checks together.
11960b57cec5SDimitry Andric CGF.EmitCheck(Checks, SanitizerHandler::ImplicitConversion, StaticArgs,
11970b57cec5SDimitry Andric {Src, Dst});
11980b57cec5SDimitry Andric }
11990b57cec5SDimitry Andric
EmitScalarCast(Value * Src,QualType SrcType,QualType DstType,llvm::Type * SrcTy,llvm::Type * DstTy,ScalarConversionOpts Opts)1200*5f7ddb14SDimitry Andric Value *ScalarExprEmitter::EmitScalarCast(Value *Src, QualType SrcType,
1201*5f7ddb14SDimitry Andric QualType DstType, llvm::Type *SrcTy,
1202*5f7ddb14SDimitry Andric llvm::Type *DstTy,
1203*5f7ddb14SDimitry Andric ScalarConversionOpts Opts) {
1204*5f7ddb14SDimitry Andric // The Element types determine the type of cast to perform.
1205*5f7ddb14SDimitry Andric llvm::Type *SrcElementTy;
1206*5f7ddb14SDimitry Andric llvm::Type *DstElementTy;
1207*5f7ddb14SDimitry Andric QualType SrcElementType;
1208*5f7ddb14SDimitry Andric QualType DstElementType;
1209*5f7ddb14SDimitry Andric if (SrcType->isMatrixType() && DstType->isMatrixType()) {
1210*5f7ddb14SDimitry Andric SrcElementTy = cast<llvm::VectorType>(SrcTy)->getElementType();
1211*5f7ddb14SDimitry Andric DstElementTy = cast<llvm::VectorType>(DstTy)->getElementType();
1212*5f7ddb14SDimitry Andric SrcElementType = SrcType->castAs<MatrixType>()->getElementType();
1213*5f7ddb14SDimitry Andric DstElementType = DstType->castAs<MatrixType>()->getElementType();
1214*5f7ddb14SDimitry Andric } else {
1215*5f7ddb14SDimitry Andric assert(!SrcType->isMatrixType() && !DstType->isMatrixType() &&
1216*5f7ddb14SDimitry Andric "cannot cast between matrix and non-matrix types");
1217*5f7ddb14SDimitry Andric SrcElementTy = SrcTy;
1218*5f7ddb14SDimitry Andric DstElementTy = DstTy;
1219*5f7ddb14SDimitry Andric SrcElementType = SrcType;
1220*5f7ddb14SDimitry Andric DstElementType = DstType;
1221*5f7ddb14SDimitry Andric }
1222*5f7ddb14SDimitry Andric
1223*5f7ddb14SDimitry Andric if (isa<llvm::IntegerType>(SrcElementTy)) {
1224*5f7ddb14SDimitry Andric bool InputSigned = SrcElementType->isSignedIntegerOrEnumerationType();
1225*5f7ddb14SDimitry Andric if (SrcElementType->isBooleanType() && Opts.TreatBooleanAsSigned) {
1226*5f7ddb14SDimitry Andric InputSigned = true;
1227*5f7ddb14SDimitry Andric }
1228*5f7ddb14SDimitry Andric
1229*5f7ddb14SDimitry Andric if (isa<llvm::IntegerType>(DstElementTy))
1230*5f7ddb14SDimitry Andric return Builder.CreateIntCast(Src, DstTy, InputSigned, "conv");
1231*5f7ddb14SDimitry Andric if (InputSigned)
1232*5f7ddb14SDimitry Andric return Builder.CreateSIToFP(Src, DstTy, "conv");
1233*5f7ddb14SDimitry Andric return Builder.CreateUIToFP(Src, DstTy, "conv");
1234*5f7ddb14SDimitry Andric }
1235*5f7ddb14SDimitry Andric
1236*5f7ddb14SDimitry Andric if (isa<llvm::IntegerType>(DstElementTy)) {
1237*5f7ddb14SDimitry Andric assert(SrcElementTy->isFloatingPointTy() && "Unknown real conversion");
1238*5f7ddb14SDimitry Andric if (DstElementType->isSignedIntegerOrEnumerationType())
1239*5f7ddb14SDimitry Andric return Builder.CreateFPToSI(Src, DstTy, "conv");
1240*5f7ddb14SDimitry Andric return Builder.CreateFPToUI(Src, DstTy, "conv");
1241*5f7ddb14SDimitry Andric }
1242*5f7ddb14SDimitry Andric
1243*5f7ddb14SDimitry Andric if (DstElementTy->getTypeID() < SrcElementTy->getTypeID())
1244*5f7ddb14SDimitry Andric return Builder.CreateFPTrunc(Src, DstTy, "conv");
1245*5f7ddb14SDimitry Andric return Builder.CreateFPExt(Src, DstTy, "conv");
1246*5f7ddb14SDimitry Andric }
1247*5f7ddb14SDimitry Andric
12480b57cec5SDimitry Andric /// Emit a conversion from the specified type to the specified destination type,
12490b57cec5SDimitry Andric /// both of which are LLVM scalar types.
EmitScalarConversion(Value * Src,QualType SrcType,QualType DstType,SourceLocation Loc,ScalarConversionOpts Opts)12500b57cec5SDimitry Andric Value *ScalarExprEmitter::EmitScalarConversion(Value *Src, QualType SrcType,
12510b57cec5SDimitry Andric QualType DstType,
12520b57cec5SDimitry Andric SourceLocation Loc,
12530b57cec5SDimitry Andric ScalarConversionOpts Opts) {
12540b57cec5SDimitry Andric // All conversions involving fixed point types should be handled by the
12550b57cec5SDimitry Andric // EmitFixedPoint family functions. This is done to prevent bloating up this
12560b57cec5SDimitry Andric // function more, and although fixed point numbers are represented by
12570b57cec5SDimitry Andric // integers, we do not want to follow any logic that assumes they should be
12580b57cec5SDimitry Andric // treated as integers.
12590b57cec5SDimitry Andric // TODO(leonardchan): When necessary, add another if statement checking for
12600b57cec5SDimitry Andric // conversions to fixed point types from other types.
12610b57cec5SDimitry Andric if (SrcType->isFixedPointType()) {
12620b57cec5SDimitry Andric if (DstType->isBooleanType())
12630b57cec5SDimitry Andric // It is important that we check this before checking if the dest type is
12640b57cec5SDimitry Andric // an integer because booleans are technically integer types.
12650b57cec5SDimitry Andric // We do not need to check the padding bit on unsigned types if unsigned
12660b57cec5SDimitry Andric // padding is enabled because overflow into this bit is undefined
12670b57cec5SDimitry Andric // behavior.
12680b57cec5SDimitry Andric return Builder.CreateIsNotNull(Src, "tobool");
1269af732203SDimitry Andric if (DstType->isFixedPointType() || DstType->isIntegerType() ||
1270af732203SDimitry Andric DstType->isRealFloatingType())
12710b57cec5SDimitry Andric return EmitFixedPointConversion(Src, SrcType, DstType, Loc);
12720b57cec5SDimitry Andric
12730b57cec5SDimitry Andric llvm_unreachable(
12740b57cec5SDimitry Andric "Unhandled scalar conversion from a fixed point type to another type.");
12750b57cec5SDimitry Andric } else if (DstType->isFixedPointType()) {
1276af732203SDimitry Andric if (SrcType->isIntegerType() || SrcType->isRealFloatingType())
12770b57cec5SDimitry Andric // This also includes converting booleans and enums to fixed point types.
12780b57cec5SDimitry Andric return EmitFixedPointConversion(Src, SrcType, DstType, Loc);
12790b57cec5SDimitry Andric
12800b57cec5SDimitry Andric llvm_unreachable(
12810b57cec5SDimitry Andric "Unhandled scalar conversion to a fixed point type from another type.");
12820b57cec5SDimitry Andric }
12830b57cec5SDimitry Andric
12840b57cec5SDimitry Andric QualType NoncanonicalSrcType = SrcType;
12850b57cec5SDimitry Andric QualType NoncanonicalDstType = DstType;
12860b57cec5SDimitry Andric
12870b57cec5SDimitry Andric SrcType = CGF.getContext().getCanonicalType(SrcType);
12880b57cec5SDimitry Andric DstType = CGF.getContext().getCanonicalType(DstType);
12890b57cec5SDimitry Andric if (SrcType == DstType) return Src;
12900b57cec5SDimitry Andric
12910b57cec5SDimitry Andric if (DstType->isVoidType()) return nullptr;
12920b57cec5SDimitry Andric
12930b57cec5SDimitry Andric llvm::Value *OrigSrc = Src;
12940b57cec5SDimitry Andric QualType OrigSrcType = SrcType;
12950b57cec5SDimitry Andric llvm::Type *SrcTy = Src->getType();
12960b57cec5SDimitry Andric
12970b57cec5SDimitry Andric // Handle conversions to bool first, they are special: comparisons against 0.
12980b57cec5SDimitry Andric if (DstType->isBooleanType())
12990b57cec5SDimitry Andric return EmitConversionToBool(Src, SrcType);
13000b57cec5SDimitry Andric
13010b57cec5SDimitry Andric llvm::Type *DstTy = ConvertType(DstType);
13020b57cec5SDimitry Andric
13030b57cec5SDimitry Andric // Cast from half through float if half isn't a native type.
13040b57cec5SDimitry Andric if (SrcType->isHalfType() && !CGF.getContext().getLangOpts().NativeHalfType) {
13050b57cec5SDimitry Andric // Cast to FP using the intrinsic if the half type itself isn't supported.
13060b57cec5SDimitry Andric if (DstTy->isFloatingPointTy()) {
13070b57cec5SDimitry Andric if (CGF.getContext().getTargetInfo().useFP16ConversionIntrinsics())
13080b57cec5SDimitry Andric return Builder.CreateCall(
13090b57cec5SDimitry Andric CGF.CGM.getIntrinsic(llvm::Intrinsic::convert_from_fp16, DstTy),
13100b57cec5SDimitry Andric Src);
13110b57cec5SDimitry Andric } else {
13120b57cec5SDimitry Andric // Cast to other types through float, using either the intrinsic or FPExt,
13130b57cec5SDimitry Andric // depending on whether the half type itself is supported
13140b57cec5SDimitry Andric // (as opposed to operations on half, available with NativeHalfType).
13150b57cec5SDimitry Andric if (CGF.getContext().getTargetInfo().useFP16ConversionIntrinsics()) {
13160b57cec5SDimitry Andric Src = Builder.CreateCall(
13170b57cec5SDimitry Andric CGF.CGM.getIntrinsic(llvm::Intrinsic::convert_from_fp16,
13180b57cec5SDimitry Andric CGF.CGM.FloatTy),
13190b57cec5SDimitry Andric Src);
13200b57cec5SDimitry Andric } else {
13210b57cec5SDimitry Andric Src = Builder.CreateFPExt(Src, CGF.CGM.FloatTy, "conv");
13220b57cec5SDimitry Andric }
13230b57cec5SDimitry Andric SrcType = CGF.getContext().FloatTy;
13240b57cec5SDimitry Andric SrcTy = CGF.FloatTy;
13250b57cec5SDimitry Andric }
13260b57cec5SDimitry Andric }
13270b57cec5SDimitry Andric
13280b57cec5SDimitry Andric // Ignore conversions like int -> uint.
13290b57cec5SDimitry Andric if (SrcTy == DstTy) {
13300b57cec5SDimitry Andric if (Opts.EmitImplicitIntegerSignChangeChecks)
13310b57cec5SDimitry Andric EmitIntegerSignChangeCheck(Src, NoncanonicalSrcType, Src,
13320b57cec5SDimitry Andric NoncanonicalDstType, Loc);
13330b57cec5SDimitry Andric
13340b57cec5SDimitry Andric return Src;
13350b57cec5SDimitry Andric }
13360b57cec5SDimitry Andric
13370b57cec5SDimitry Andric // Handle pointer conversions next: pointers can only be converted to/from
13380b57cec5SDimitry Andric // other pointers and integers. Check for pointer types in terms of LLVM, as
13390b57cec5SDimitry Andric // some native types (like Obj-C id) may map to a pointer type.
13400b57cec5SDimitry Andric if (auto DstPT = dyn_cast<llvm::PointerType>(DstTy)) {
13410b57cec5SDimitry Andric // The source value may be an integer, or a pointer.
13420b57cec5SDimitry Andric if (isa<llvm::PointerType>(SrcTy))
13430b57cec5SDimitry Andric return Builder.CreateBitCast(Src, DstTy, "conv");
13440b57cec5SDimitry Andric
13450b57cec5SDimitry Andric assert(SrcType->isIntegerType() && "Not ptr->ptr or int->ptr conversion?");
13460b57cec5SDimitry Andric // First, convert to the correct width so that we control the kind of
13470b57cec5SDimitry Andric // extension.
13480b57cec5SDimitry Andric llvm::Type *MiddleTy = CGF.CGM.getDataLayout().getIntPtrType(DstPT);
13490b57cec5SDimitry Andric bool InputSigned = SrcType->isSignedIntegerOrEnumerationType();
13500b57cec5SDimitry Andric llvm::Value* IntResult =
13510b57cec5SDimitry Andric Builder.CreateIntCast(Src, MiddleTy, InputSigned, "conv");
13520b57cec5SDimitry Andric // Then, cast to pointer.
13530b57cec5SDimitry Andric return Builder.CreateIntToPtr(IntResult, DstTy, "conv");
13540b57cec5SDimitry Andric }
13550b57cec5SDimitry Andric
13560b57cec5SDimitry Andric if (isa<llvm::PointerType>(SrcTy)) {
13570b57cec5SDimitry Andric // Must be an ptr to int cast.
13580b57cec5SDimitry Andric assert(isa<llvm::IntegerType>(DstTy) && "not ptr->int?");
13590b57cec5SDimitry Andric return Builder.CreatePtrToInt(Src, DstTy, "conv");
13600b57cec5SDimitry Andric }
13610b57cec5SDimitry Andric
13620b57cec5SDimitry Andric // A scalar can be splatted to an extended vector of the same element type
13630b57cec5SDimitry Andric if (DstType->isExtVectorType() && !SrcType->isVectorType()) {
13640b57cec5SDimitry Andric // Sema should add casts to make sure that the source expression's type is
13650b57cec5SDimitry Andric // the same as the vector's element type (sans qualifiers)
13660b57cec5SDimitry Andric assert(DstType->castAs<ExtVectorType>()->getElementType().getTypePtr() ==
13670b57cec5SDimitry Andric SrcType.getTypePtr() &&
13680b57cec5SDimitry Andric "Splatted expr doesn't match with vector element type?");
13690b57cec5SDimitry Andric
13700b57cec5SDimitry Andric // Splat the element across to all elements
1371af732203SDimitry Andric unsigned NumElements = cast<llvm::FixedVectorType>(DstTy)->getNumElements();
13720b57cec5SDimitry Andric return Builder.CreateVectorSplat(NumElements, Src, "splat");
13730b57cec5SDimitry Andric }
13740b57cec5SDimitry Andric
1375*5f7ddb14SDimitry Andric if (SrcType->isMatrixType() && DstType->isMatrixType())
1376*5f7ddb14SDimitry Andric return EmitScalarCast(Src, SrcType, DstType, SrcTy, DstTy, Opts);
1377*5f7ddb14SDimitry Andric
13780b57cec5SDimitry Andric if (isa<llvm::VectorType>(SrcTy) || isa<llvm::VectorType>(DstTy)) {
13790b57cec5SDimitry Andric // Allow bitcast from vector to integer/fp of the same size.
13800b57cec5SDimitry Andric unsigned SrcSize = SrcTy->getPrimitiveSizeInBits();
13810b57cec5SDimitry Andric unsigned DstSize = DstTy->getPrimitiveSizeInBits();
13820b57cec5SDimitry Andric if (SrcSize == DstSize)
13830b57cec5SDimitry Andric return Builder.CreateBitCast(Src, DstTy, "conv");
13840b57cec5SDimitry Andric
13850b57cec5SDimitry Andric // Conversions between vectors of different sizes are not allowed except
13860b57cec5SDimitry Andric // when vectors of half are involved. Operations on storage-only half
13870b57cec5SDimitry Andric // vectors require promoting half vector operands to float vectors and
13880b57cec5SDimitry Andric // truncating the result, which is either an int or float vector, to a
13890b57cec5SDimitry Andric // short or half vector.
13900b57cec5SDimitry Andric
13910b57cec5SDimitry Andric // Source and destination are both expected to be vectors.
13925ffd83dbSDimitry Andric llvm::Type *SrcElementTy = cast<llvm::VectorType>(SrcTy)->getElementType();
13935ffd83dbSDimitry Andric llvm::Type *DstElementTy = cast<llvm::VectorType>(DstTy)->getElementType();
13940b57cec5SDimitry Andric (void)DstElementTy;
13950b57cec5SDimitry Andric
13960b57cec5SDimitry Andric assert(((SrcElementTy->isIntegerTy() &&
13970b57cec5SDimitry Andric DstElementTy->isIntegerTy()) ||
13980b57cec5SDimitry Andric (SrcElementTy->isFloatingPointTy() &&
13990b57cec5SDimitry Andric DstElementTy->isFloatingPointTy())) &&
14000b57cec5SDimitry Andric "unexpected conversion between a floating-point vector and an "
14010b57cec5SDimitry Andric "integer vector");
14020b57cec5SDimitry Andric
14030b57cec5SDimitry Andric // Truncate an i32 vector to an i16 vector.
14040b57cec5SDimitry Andric if (SrcElementTy->isIntegerTy())
14050b57cec5SDimitry Andric return Builder.CreateIntCast(Src, DstTy, false, "conv");
14060b57cec5SDimitry Andric
14070b57cec5SDimitry Andric // Truncate a float vector to a half vector.
14080b57cec5SDimitry Andric if (SrcSize > DstSize)
14090b57cec5SDimitry Andric return Builder.CreateFPTrunc(Src, DstTy, "conv");
14100b57cec5SDimitry Andric
14110b57cec5SDimitry Andric // Promote a half vector to a float vector.
14120b57cec5SDimitry Andric return Builder.CreateFPExt(Src, DstTy, "conv");
14130b57cec5SDimitry Andric }
14140b57cec5SDimitry Andric
14150b57cec5SDimitry Andric // Finally, we have the arithmetic types: real int/float.
14160b57cec5SDimitry Andric Value *Res = nullptr;
14170b57cec5SDimitry Andric llvm::Type *ResTy = DstTy;
14180b57cec5SDimitry Andric
14190b57cec5SDimitry Andric // An overflowing conversion has undefined behavior if either the source type
14200b57cec5SDimitry Andric // or the destination type is a floating-point type. However, we consider the
14210b57cec5SDimitry Andric // range of representable values for all floating-point types to be
14220b57cec5SDimitry Andric // [-inf,+inf], so no overflow can ever happen when the destination type is a
14230b57cec5SDimitry Andric // floating-point type.
14240b57cec5SDimitry Andric if (CGF.SanOpts.has(SanitizerKind::FloatCastOverflow) &&
14250b57cec5SDimitry Andric OrigSrcType->isFloatingType())
14260b57cec5SDimitry Andric EmitFloatConversionCheck(OrigSrc, OrigSrcType, Src, SrcType, DstType, DstTy,
14270b57cec5SDimitry Andric Loc);
14280b57cec5SDimitry Andric
14290b57cec5SDimitry Andric // Cast to half through float if half isn't a native type.
14300b57cec5SDimitry Andric if (DstType->isHalfType() && !CGF.getContext().getLangOpts().NativeHalfType) {
14310b57cec5SDimitry Andric // Make sure we cast in a single step if from another FP type.
14320b57cec5SDimitry Andric if (SrcTy->isFloatingPointTy()) {
14330b57cec5SDimitry Andric // Use the intrinsic if the half type itself isn't supported
14340b57cec5SDimitry Andric // (as opposed to operations on half, available with NativeHalfType).
14350b57cec5SDimitry Andric if (CGF.getContext().getTargetInfo().useFP16ConversionIntrinsics())
14360b57cec5SDimitry Andric return Builder.CreateCall(
14370b57cec5SDimitry Andric CGF.CGM.getIntrinsic(llvm::Intrinsic::convert_to_fp16, SrcTy), Src);
14380b57cec5SDimitry Andric // If the half type is supported, just use an fptrunc.
14390b57cec5SDimitry Andric return Builder.CreateFPTrunc(Src, DstTy);
14400b57cec5SDimitry Andric }
14410b57cec5SDimitry Andric DstTy = CGF.FloatTy;
14420b57cec5SDimitry Andric }
14430b57cec5SDimitry Andric
1444*5f7ddb14SDimitry Andric Res = EmitScalarCast(Src, SrcType, DstType, SrcTy, DstTy, Opts);
14450b57cec5SDimitry Andric
14460b57cec5SDimitry Andric if (DstTy != ResTy) {
14470b57cec5SDimitry Andric if (CGF.getContext().getTargetInfo().useFP16ConversionIntrinsics()) {
14480b57cec5SDimitry Andric assert(ResTy->isIntegerTy(16) && "Only half FP requires extra conversion");
14490b57cec5SDimitry Andric Res = Builder.CreateCall(
14500b57cec5SDimitry Andric CGF.CGM.getIntrinsic(llvm::Intrinsic::convert_to_fp16, CGF.CGM.FloatTy),
14510b57cec5SDimitry Andric Res);
14520b57cec5SDimitry Andric } else {
14530b57cec5SDimitry Andric Res = Builder.CreateFPTrunc(Res, ResTy, "conv");
14540b57cec5SDimitry Andric }
14550b57cec5SDimitry Andric }
14560b57cec5SDimitry Andric
14570b57cec5SDimitry Andric if (Opts.EmitImplicitIntegerTruncationChecks)
14580b57cec5SDimitry Andric EmitIntegerTruncationCheck(Src, NoncanonicalSrcType, Res,
14590b57cec5SDimitry Andric NoncanonicalDstType, Loc);
14600b57cec5SDimitry Andric
14610b57cec5SDimitry Andric if (Opts.EmitImplicitIntegerSignChangeChecks)
14620b57cec5SDimitry Andric EmitIntegerSignChangeCheck(Src, NoncanonicalSrcType, Res,
14630b57cec5SDimitry Andric NoncanonicalDstType, Loc);
14640b57cec5SDimitry Andric
14650b57cec5SDimitry Andric return Res;
14660b57cec5SDimitry Andric }
14670b57cec5SDimitry Andric
EmitFixedPointConversion(Value * Src,QualType SrcTy,QualType DstTy,SourceLocation Loc)14680b57cec5SDimitry Andric Value *ScalarExprEmitter::EmitFixedPointConversion(Value *Src, QualType SrcTy,
14690b57cec5SDimitry Andric QualType DstTy,
14700b57cec5SDimitry Andric SourceLocation Loc) {
1471af732203SDimitry Andric llvm::FixedPointBuilder<CGBuilderTy> FPBuilder(Builder);
1472af732203SDimitry Andric llvm::Value *Result;
1473af732203SDimitry Andric if (SrcTy->isRealFloatingType())
1474af732203SDimitry Andric Result = FPBuilder.CreateFloatingToFixed(Src,
1475af732203SDimitry Andric CGF.getContext().getFixedPointSemantics(DstTy));
1476af732203SDimitry Andric else if (DstTy->isRealFloatingType())
1477af732203SDimitry Andric Result = FPBuilder.CreateFixedToFloating(Src,
1478af732203SDimitry Andric CGF.getContext().getFixedPointSemantics(SrcTy),
1479af732203SDimitry Andric ConvertType(DstTy));
1480af732203SDimitry Andric else {
1481af732203SDimitry Andric auto SrcFPSema = CGF.getContext().getFixedPointSemantics(SrcTy);
1482af732203SDimitry Andric auto DstFPSema = CGF.getContext().getFixedPointSemantics(DstTy);
14830b57cec5SDimitry Andric
1484af732203SDimitry Andric if (DstTy->isIntegerType())
1485af732203SDimitry Andric Result = FPBuilder.CreateFixedToInteger(Src, SrcFPSema,
1486af732203SDimitry Andric DstFPSema.getWidth(),
1487af732203SDimitry Andric DstFPSema.isSigned());
1488af732203SDimitry Andric else if (SrcTy->isIntegerType())
1489af732203SDimitry Andric Result = FPBuilder.CreateIntegerToFixed(Src, SrcFPSema.isSigned(),
1490af732203SDimitry Andric DstFPSema);
1491af732203SDimitry Andric else
1492af732203SDimitry Andric Result = FPBuilder.CreateFixedToFixed(Src, SrcFPSema, DstFPSema);
14930b57cec5SDimitry Andric }
14940b57cec5SDimitry Andric return Result;
14950b57cec5SDimitry Andric }
14960b57cec5SDimitry Andric
14970b57cec5SDimitry Andric /// Emit a conversion from the specified complex type to the specified
14980b57cec5SDimitry Andric /// destination type, where the destination type is an LLVM scalar type.
EmitComplexToScalarConversion(CodeGenFunction::ComplexPairTy Src,QualType SrcTy,QualType DstTy,SourceLocation Loc)14990b57cec5SDimitry Andric Value *ScalarExprEmitter::EmitComplexToScalarConversion(
15000b57cec5SDimitry Andric CodeGenFunction::ComplexPairTy Src, QualType SrcTy, QualType DstTy,
15010b57cec5SDimitry Andric SourceLocation Loc) {
15020b57cec5SDimitry Andric // Get the source element type.
15030b57cec5SDimitry Andric SrcTy = SrcTy->castAs<ComplexType>()->getElementType();
15040b57cec5SDimitry Andric
15050b57cec5SDimitry Andric // Handle conversions to bool first, they are special: comparisons against 0.
15060b57cec5SDimitry Andric if (DstTy->isBooleanType()) {
15070b57cec5SDimitry Andric // Complex != 0 -> (Real != 0) | (Imag != 0)
15080b57cec5SDimitry Andric Src.first = EmitScalarConversion(Src.first, SrcTy, DstTy, Loc);
15090b57cec5SDimitry Andric Src.second = EmitScalarConversion(Src.second, SrcTy, DstTy, Loc);
15100b57cec5SDimitry Andric return Builder.CreateOr(Src.first, Src.second, "tobool");
15110b57cec5SDimitry Andric }
15120b57cec5SDimitry Andric
15130b57cec5SDimitry Andric // C99 6.3.1.7p2: "When a value of complex type is converted to a real type,
15140b57cec5SDimitry Andric // the imaginary part of the complex value is discarded and the value of the
15150b57cec5SDimitry Andric // real part is converted according to the conversion rules for the
15160b57cec5SDimitry Andric // corresponding real type.
15170b57cec5SDimitry Andric return EmitScalarConversion(Src.first, SrcTy, DstTy, Loc);
15180b57cec5SDimitry Andric }
15190b57cec5SDimitry Andric
EmitNullValue(QualType Ty)15200b57cec5SDimitry Andric Value *ScalarExprEmitter::EmitNullValue(QualType Ty) {
15210b57cec5SDimitry Andric return CGF.EmitFromMemory(CGF.CGM.EmitNullConstant(Ty), Ty);
15220b57cec5SDimitry Andric }
15230b57cec5SDimitry Andric
15240b57cec5SDimitry Andric /// Emit a sanitization check for the given "binary" operation (which
15250b57cec5SDimitry Andric /// might actually be a unary increment which has been lowered to a binary
15260b57cec5SDimitry Andric /// operation). The check passes if all values in \p Checks (which are \c i1),
15270b57cec5SDimitry Andric /// are \c true.
EmitBinOpCheck(ArrayRef<std::pair<Value *,SanitizerMask>> Checks,const BinOpInfo & Info)15280b57cec5SDimitry Andric void ScalarExprEmitter::EmitBinOpCheck(
15290b57cec5SDimitry Andric ArrayRef<std::pair<Value *, SanitizerMask>> Checks, const BinOpInfo &Info) {
15300b57cec5SDimitry Andric assert(CGF.IsSanitizerScope);
15310b57cec5SDimitry Andric SanitizerHandler Check;
15320b57cec5SDimitry Andric SmallVector<llvm::Constant *, 4> StaticData;
15330b57cec5SDimitry Andric SmallVector<llvm::Value *, 2> DynamicData;
15340b57cec5SDimitry Andric
15350b57cec5SDimitry Andric BinaryOperatorKind Opcode = Info.Opcode;
15360b57cec5SDimitry Andric if (BinaryOperator::isCompoundAssignmentOp(Opcode))
15370b57cec5SDimitry Andric Opcode = BinaryOperator::getOpForCompoundAssignment(Opcode);
15380b57cec5SDimitry Andric
15390b57cec5SDimitry Andric StaticData.push_back(CGF.EmitCheckSourceLocation(Info.E->getExprLoc()));
15400b57cec5SDimitry Andric const UnaryOperator *UO = dyn_cast<UnaryOperator>(Info.E);
15410b57cec5SDimitry Andric if (UO && UO->getOpcode() == UO_Minus) {
15420b57cec5SDimitry Andric Check = SanitizerHandler::NegateOverflow;
15430b57cec5SDimitry Andric StaticData.push_back(CGF.EmitCheckTypeDescriptor(UO->getType()));
15440b57cec5SDimitry Andric DynamicData.push_back(Info.RHS);
15450b57cec5SDimitry Andric } else {
15460b57cec5SDimitry Andric if (BinaryOperator::isShiftOp(Opcode)) {
15470b57cec5SDimitry Andric // Shift LHS negative or too large, or RHS out of bounds.
15480b57cec5SDimitry Andric Check = SanitizerHandler::ShiftOutOfBounds;
15490b57cec5SDimitry Andric const BinaryOperator *BO = cast<BinaryOperator>(Info.E);
15500b57cec5SDimitry Andric StaticData.push_back(
15510b57cec5SDimitry Andric CGF.EmitCheckTypeDescriptor(BO->getLHS()->getType()));
15520b57cec5SDimitry Andric StaticData.push_back(
15530b57cec5SDimitry Andric CGF.EmitCheckTypeDescriptor(BO->getRHS()->getType()));
15540b57cec5SDimitry Andric } else if (Opcode == BO_Div || Opcode == BO_Rem) {
15550b57cec5SDimitry Andric // Divide or modulo by zero, or signed overflow (eg INT_MAX / -1).
15560b57cec5SDimitry Andric Check = SanitizerHandler::DivremOverflow;
15570b57cec5SDimitry Andric StaticData.push_back(CGF.EmitCheckTypeDescriptor(Info.Ty));
15580b57cec5SDimitry Andric } else {
15590b57cec5SDimitry Andric // Arithmetic overflow (+, -, *).
15600b57cec5SDimitry Andric switch (Opcode) {
15610b57cec5SDimitry Andric case BO_Add: Check = SanitizerHandler::AddOverflow; break;
15620b57cec5SDimitry Andric case BO_Sub: Check = SanitizerHandler::SubOverflow; break;
15630b57cec5SDimitry Andric case BO_Mul: Check = SanitizerHandler::MulOverflow; break;
15640b57cec5SDimitry Andric default: llvm_unreachable("unexpected opcode for bin op check");
15650b57cec5SDimitry Andric }
15660b57cec5SDimitry Andric StaticData.push_back(CGF.EmitCheckTypeDescriptor(Info.Ty));
15670b57cec5SDimitry Andric }
15680b57cec5SDimitry Andric DynamicData.push_back(Info.LHS);
15690b57cec5SDimitry Andric DynamicData.push_back(Info.RHS);
15700b57cec5SDimitry Andric }
15710b57cec5SDimitry Andric
15720b57cec5SDimitry Andric CGF.EmitCheck(Checks, Check, StaticData, DynamicData);
15730b57cec5SDimitry Andric }
15740b57cec5SDimitry Andric
15750b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
15760b57cec5SDimitry Andric // Visitor Methods
15770b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
15780b57cec5SDimitry Andric
VisitExpr(Expr * E)15790b57cec5SDimitry Andric Value *ScalarExprEmitter::VisitExpr(Expr *E) {
15800b57cec5SDimitry Andric CGF.ErrorUnsupported(E, "scalar expression");
15810b57cec5SDimitry Andric if (E->getType()->isVoidType())
15820b57cec5SDimitry Andric return nullptr;
15830b57cec5SDimitry Andric return llvm::UndefValue::get(CGF.ConvertType(E->getType()));
15840b57cec5SDimitry Andric }
15850b57cec5SDimitry Andric
1586*5f7ddb14SDimitry Andric Value *
VisitSYCLUniqueStableNameExpr(SYCLUniqueStableNameExpr * E)1587*5f7ddb14SDimitry Andric ScalarExprEmitter::VisitSYCLUniqueStableNameExpr(SYCLUniqueStableNameExpr *E) {
1588*5f7ddb14SDimitry Andric ASTContext &Context = CGF.getContext();
1589*5f7ddb14SDimitry Andric llvm::Optional<LangAS> GlobalAS =
1590*5f7ddb14SDimitry Andric Context.getTargetInfo().getConstantAddressSpace();
1591*5f7ddb14SDimitry Andric llvm::Constant *GlobalConstStr = Builder.CreateGlobalStringPtr(
1592*5f7ddb14SDimitry Andric E->ComputeName(Context), "__usn_str",
1593*5f7ddb14SDimitry Andric static_cast<unsigned>(GlobalAS.getValueOr(LangAS::Default)));
1594*5f7ddb14SDimitry Andric
1595*5f7ddb14SDimitry Andric unsigned ExprAS = Context.getTargetAddressSpace(E->getType());
1596*5f7ddb14SDimitry Andric
1597*5f7ddb14SDimitry Andric if (GlobalConstStr->getType()->getPointerAddressSpace() == ExprAS)
1598*5f7ddb14SDimitry Andric return GlobalConstStr;
1599*5f7ddb14SDimitry Andric
1600*5f7ddb14SDimitry Andric llvm::Type *EltTy = GlobalConstStr->getType()->getPointerElementType();
1601*5f7ddb14SDimitry Andric llvm::PointerType *NewPtrTy = llvm::PointerType::get(EltTy, ExprAS);
1602*5f7ddb14SDimitry Andric return Builder.CreateAddrSpaceCast(GlobalConstStr, NewPtrTy, "usn_addr_cast");
1603*5f7ddb14SDimitry Andric }
1604*5f7ddb14SDimitry Andric
VisitShuffleVectorExpr(ShuffleVectorExpr * E)16050b57cec5SDimitry Andric Value *ScalarExprEmitter::VisitShuffleVectorExpr(ShuffleVectorExpr *E) {
16060b57cec5SDimitry Andric // Vector Mask Case
16070b57cec5SDimitry Andric if (E->getNumSubExprs() == 2) {
16080b57cec5SDimitry Andric Value *LHS = CGF.EmitScalarExpr(E->getExpr(0));
16090b57cec5SDimitry Andric Value *RHS = CGF.EmitScalarExpr(E->getExpr(1));
16100b57cec5SDimitry Andric Value *Mask;
16110b57cec5SDimitry Andric
1612af732203SDimitry Andric auto *LTy = cast<llvm::FixedVectorType>(LHS->getType());
16130b57cec5SDimitry Andric unsigned LHSElts = LTy->getNumElements();
16140b57cec5SDimitry Andric
16150b57cec5SDimitry Andric Mask = RHS;
16160b57cec5SDimitry Andric
1617af732203SDimitry Andric auto *MTy = cast<llvm::FixedVectorType>(Mask->getType());
16180b57cec5SDimitry Andric
16190b57cec5SDimitry Andric // Mask off the high bits of each shuffle index.
16200b57cec5SDimitry Andric Value *MaskBits =
16210b57cec5SDimitry Andric llvm::ConstantInt::get(MTy, llvm::NextPowerOf2(LHSElts - 1) - 1);
16220b57cec5SDimitry Andric Mask = Builder.CreateAnd(Mask, MaskBits, "mask");
16230b57cec5SDimitry Andric
16240b57cec5SDimitry Andric // newv = undef
16250b57cec5SDimitry Andric // mask = mask & maskbits
16260b57cec5SDimitry Andric // for each elt
16270b57cec5SDimitry Andric // n = extract mask i
16280b57cec5SDimitry Andric // x = extract val n
16290b57cec5SDimitry Andric // newv = insert newv, x, i
16305ffd83dbSDimitry Andric auto *RTy = llvm::FixedVectorType::get(LTy->getElementType(),
16310b57cec5SDimitry Andric MTy->getNumElements());
16320b57cec5SDimitry Andric Value* NewV = llvm::UndefValue::get(RTy);
16330b57cec5SDimitry Andric for (unsigned i = 0, e = MTy->getNumElements(); i != e; ++i) {
16340b57cec5SDimitry Andric Value *IIndx = llvm::ConstantInt::get(CGF.SizeTy, i);
16350b57cec5SDimitry Andric Value *Indx = Builder.CreateExtractElement(Mask, IIndx, "shuf_idx");
16360b57cec5SDimitry Andric
16370b57cec5SDimitry Andric Value *VExt = Builder.CreateExtractElement(LHS, Indx, "shuf_elt");
16380b57cec5SDimitry Andric NewV = Builder.CreateInsertElement(NewV, VExt, IIndx, "shuf_ins");
16390b57cec5SDimitry Andric }
16400b57cec5SDimitry Andric return NewV;
16410b57cec5SDimitry Andric }
16420b57cec5SDimitry Andric
16430b57cec5SDimitry Andric Value* V1 = CGF.EmitScalarExpr(E->getExpr(0));
16440b57cec5SDimitry Andric Value* V2 = CGF.EmitScalarExpr(E->getExpr(1));
16450b57cec5SDimitry Andric
16465ffd83dbSDimitry Andric SmallVector<int, 32> Indices;
16470b57cec5SDimitry Andric for (unsigned i = 2; i < E->getNumSubExprs(); ++i) {
16480b57cec5SDimitry Andric llvm::APSInt Idx = E->getShuffleMaskIdx(CGF.getContext(), i-2);
16490b57cec5SDimitry Andric // Check for -1 and output it as undef in the IR.
16500b57cec5SDimitry Andric if (Idx.isSigned() && Idx.isAllOnesValue())
16515ffd83dbSDimitry Andric Indices.push_back(-1);
16520b57cec5SDimitry Andric else
16535ffd83dbSDimitry Andric Indices.push_back(Idx.getZExtValue());
16540b57cec5SDimitry Andric }
16550b57cec5SDimitry Andric
16565ffd83dbSDimitry Andric return Builder.CreateShuffleVector(V1, V2, Indices, "shuffle");
16570b57cec5SDimitry Andric }
16580b57cec5SDimitry Andric
VisitConvertVectorExpr(ConvertVectorExpr * E)16590b57cec5SDimitry Andric Value *ScalarExprEmitter::VisitConvertVectorExpr(ConvertVectorExpr *E) {
16600b57cec5SDimitry Andric QualType SrcType = E->getSrcExpr()->getType(),
16610b57cec5SDimitry Andric DstType = E->getType();
16620b57cec5SDimitry Andric
16630b57cec5SDimitry Andric Value *Src = CGF.EmitScalarExpr(E->getSrcExpr());
16640b57cec5SDimitry Andric
16650b57cec5SDimitry Andric SrcType = CGF.getContext().getCanonicalType(SrcType);
16660b57cec5SDimitry Andric DstType = CGF.getContext().getCanonicalType(DstType);
16670b57cec5SDimitry Andric if (SrcType == DstType) return Src;
16680b57cec5SDimitry Andric
16690b57cec5SDimitry Andric assert(SrcType->isVectorType() &&
16700b57cec5SDimitry Andric "ConvertVector source type must be a vector");
16710b57cec5SDimitry Andric assert(DstType->isVectorType() &&
16720b57cec5SDimitry Andric "ConvertVector destination type must be a vector");
16730b57cec5SDimitry Andric
16740b57cec5SDimitry Andric llvm::Type *SrcTy = Src->getType();
16750b57cec5SDimitry Andric llvm::Type *DstTy = ConvertType(DstType);
16760b57cec5SDimitry Andric
16770b57cec5SDimitry Andric // Ignore conversions like int -> uint.
16780b57cec5SDimitry Andric if (SrcTy == DstTy)
16790b57cec5SDimitry Andric return Src;
16800b57cec5SDimitry Andric
1681a7dea167SDimitry Andric QualType SrcEltType = SrcType->castAs<VectorType>()->getElementType(),
1682a7dea167SDimitry Andric DstEltType = DstType->castAs<VectorType>()->getElementType();
16830b57cec5SDimitry Andric
16840b57cec5SDimitry Andric assert(SrcTy->isVectorTy() &&
16850b57cec5SDimitry Andric "ConvertVector source IR type must be a vector");
16860b57cec5SDimitry Andric assert(DstTy->isVectorTy() &&
16870b57cec5SDimitry Andric "ConvertVector destination IR type must be a vector");
16880b57cec5SDimitry Andric
16895ffd83dbSDimitry Andric llvm::Type *SrcEltTy = cast<llvm::VectorType>(SrcTy)->getElementType(),
16905ffd83dbSDimitry Andric *DstEltTy = cast<llvm::VectorType>(DstTy)->getElementType();
16910b57cec5SDimitry Andric
16920b57cec5SDimitry Andric if (DstEltType->isBooleanType()) {
16930b57cec5SDimitry Andric assert((SrcEltTy->isFloatingPointTy() ||
16940b57cec5SDimitry Andric isa<llvm::IntegerType>(SrcEltTy)) && "Unknown boolean conversion");
16950b57cec5SDimitry Andric
16960b57cec5SDimitry Andric llvm::Value *Zero = llvm::Constant::getNullValue(SrcTy);
16970b57cec5SDimitry Andric if (SrcEltTy->isFloatingPointTy()) {
16980b57cec5SDimitry Andric return Builder.CreateFCmpUNE(Src, Zero, "tobool");
16990b57cec5SDimitry Andric } else {
17000b57cec5SDimitry Andric return Builder.CreateICmpNE(Src, Zero, "tobool");
17010b57cec5SDimitry Andric }
17020b57cec5SDimitry Andric }
17030b57cec5SDimitry Andric
17040b57cec5SDimitry Andric // We have the arithmetic types: real int/float.
17050b57cec5SDimitry Andric Value *Res = nullptr;
17060b57cec5SDimitry Andric
17070b57cec5SDimitry Andric if (isa<llvm::IntegerType>(SrcEltTy)) {
17080b57cec5SDimitry Andric bool InputSigned = SrcEltType->isSignedIntegerOrEnumerationType();
17090b57cec5SDimitry Andric if (isa<llvm::IntegerType>(DstEltTy))
17100b57cec5SDimitry Andric Res = Builder.CreateIntCast(Src, DstTy, InputSigned, "conv");
17110b57cec5SDimitry Andric else if (InputSigned)
17120b57cec5SDimitry Andric Res = Builder.CreateSIToFP(Src, DstTy, "conv");
17130b57cec5SDimitry Andric else
17140b57cec5SDimitry Andric Res = Builder.CreateUIToFP(Src, DstTy, "conv");
17150b57cec5SDimitry Andric } else if (isa<llvm::IntegerType>(DstEltTy)) {
17160b57cec5SDimitry Andric assert(SrcEltTy->isFloatingPointTy() && "Unknown real conversion");
17170b57cec5SDimitry Andric if (DstEltType->isSignedIntegerOrEnumerationType())
17180b57cec5SDimitry Andric Res = Builder.CreateFPToSI(Src, DstTy, "conv");
17190b57cec5SDimitry Andric else
17200b57cec5SDimitry Andric Res = Builder.CreateFPToUI(Src, DstTy, "conv");
17210b57cec5SDimitry Andric } else {
17220b57cec5SDimitry Andric assert(SrcEltTy->isFloatingPointTy() && DstEltTy->isFloatingPointTy() &&
17230b57cec5SDimitry Andric "Unknown real conversion");
17240b57cec5SDimitry Andric if (DstEltTy->getTypeID() < SrcEltTy->getTypeID())
17250b57cec5SDimitry Andric Res = Builder.CreateFPTrunc(Src, DstTy, "conv");
17260b57cec5SDimitry Andric else
17270b57cec5SDimitry Andric Res = Builder.CreateFPExt(Src, DstTy, "conv");
17280b57cec5SDimitry Andric }
17290b57cec5SDimitry Andric
17300b57cec5SDimitry Andric return Res;
17310b57cec5SDimitry Andric }
17320b57cec5SDimitry Andric
VisitMemberExpr(MemberExpr * E)17330b57cec5SDimitry Andric Value *ScalarExprEmitter::VisitMemberExpr(MemberExpr *E) {
17340b57cec5SDimitry Andric if (CodeGenFunction::ConstantEmission Constant = CGF.tryEmitAsConstant(E)) {
17350b57cec5SDimitry Andric CGF.EmitIgnoredExpr(E->getBase());
17360b57cec5SDimitry Andric return CGF.emitScalarConstant(Constant, E);
17370b57cec5SDimitry Andric } else {
17380b57cec5SDimitry Andric Expr::EvalResult Result;
17390b57cec5SDimitry Andric if (E->EvaluateAsInt(Result, CGF.getContext(), Expr::SE_AllowSideEffects)) {
17400b57cec5SDimitry Andric llvm::APSInt Value = Result.Val.getInt();
17410b57cec5SDimitry Andric CGF.EmitIgnoredExpr(E->getBase());
17420b57cec5SDimitry Andric return Builder.getInt(Value);
17430b57cec5SDimitry Andric }
17440b57cec5SDimitry Andric }
17450b57cec5SDimitry Andric
17460b57cec5SDimitry Andric return EmitLoadOfLValue(E);
17470b57cec5SDimitry Andric }
17480b57cec5SDimitry Andric
VisitArraySubscriptExpr(ArraySubscriptExpr * E)17490b57cec5SDimitry Andric Value *ScalarExprEmitter::VisitArraySubscriptExpr(ArraySubscriptExpr *E) {
17500b57cec5SDimitry Andric TestAndClearIgnoreResultAssign();
17510b57cec5SDimitry Andric
17520b57cec5SDimitry Andric // Emit subscript expressions in rvalue context's. For most cases, this just
17530b57cec5SDimitry Andric // loads the lvalue formed by the subscript expr. However, we have to be
17540b57cec5SDimitry Andric // careful, because the base of a vector subscript is occasionally an rvalue,
17550b57cec5SDimitry Andric // so we can't get it as an lvalue.
17560b57cec5SDimitry Andric if (!E->getBase()->getType()->isVectorType())
17570b57cec5SDimitry Andric return EmitLoadOfLValue(E);
17580b57cec5SDimitry Andric
17590b57cec5SDimitry Andric // Handle the vector case. The base must be a vector, the index must be an
17600b57cec5SDimitry Andric // integer value.
17610b57cec5SDimitry Andric Value *Base = Visit(E->getBase());
17620b57cec5SDimitry Andric Value *Idx = Visit(E->getIdx());
17630b57cec5SDimitry Andric QualType IdxTy = E->getIdx()->getType();
17640b57cec5SDimitry Andric
17650b57cec5SDimitry Andric if (CGF.SanOpts.has(SanitizerKind::ArrayBounds))
17660b57cec5SDimitry Andric CGF.EmitBoundsCheck(E, E->getBase(), Idx, IdxTy, /*Accessed*/true);
17670b57cec5SDimitry Andric
17680b57cec5SDimitry Andric return Builder.CreateExtractElement(Base, Idx, "vecext");
17690b57cec5SDimitry Andric }
17700b57cec5SDimitry Andric
VisitMatrixSubscriptExpr(MatrixSubscriptExpr * E)17715ffd83dbSDimitry Andric Value *ScalarExprEmitter::VisitMatrixSubscriptExpr(MatrixSubscriptExpr *E) {
17725ffd83dbSDimitry Andric TestAndClearIgnoreResultAssign();
17735ffd83dbSDimitry Andric
17745ffd83dbSDimitry Andric // Handle the vector case. The base must be a vector, the index must be an
17755ffd83dbSDimitry Andric // integer value.
17765ffd83dbSDimitry Andric Value *RowIdx = Visit(E->getRowIdx());
17775ffd83dbSDimitry Andric Value *ColumnIdx = Visit(E->getColumnIdx());
17785ffd83dbSDimitry Andric Value *Matrix = Visit(E->getBase());
17795ffd83dbSDimitry Andric
17805ffd83dbSDimitry Andric // TODO: Should we emit bounds checks with SanitizerKind::ArrayBounds?
17815ffd83dbSDimitry Andric llvm::MatrixBuilder<CGBuilderTy> MB(Builder);
17825ffd83dbSDimitry Andric return MB.CreateExtractElement(
17835ffd83dbSDimitry Andric Matrix, RowIdx, ColumnIdx,
1784*5f7ddb14SDimitry Andric E->getBase()->getType()->castAs<ConstantMatrixType>()->getNumRows());
17850b57cec5SDimitry Andric }
17860b57cec5SDimitry Andric
getMaskElt(llvm::ShuffleVectorInst * SVI,unsigned Idx,unsigned Off)17875ffd83dbSDimitry Andric static int getMaskElt(llvm::ShuffleVectorInst *SVI, unsigned Idx,
17885ffd83dbSDimitry Andric unsigned Off) {
17895ffd83dbSDimitry Andric int MV = SVI->getMaskValue(Idx);
17905ffd83dbSDimitry Andric if (MV == -1)
17915ffd83dbSDimitry Andric return -1;
17925ffd83dbSDimitry Andric return Off + MV;
17930b57cec5SDimitry Andric }
17945ffd83dbSDimitry Andric
getAsInt32(llvm::ConstantInt * C,llvm::Type * I32Ty)17955ffd83dbSDimitry Andric static int getAsInt32(llvm::ConstantInt *C, llvm::Type *I32Ty) {
17965ffd83dbSDimitry Andric assert(llvm::ConstantInt::isValueValidForType(I32Ty, C->getZExtValue()) &&
17975ffd83dbSDimitry Andric "Index operand too large for shufflevector mask!");
17985ffd83dbSDimitry Andric return C->getZExtValue();
17990b57cec5SDimitry Andric }
18000b57cec5SDimitry Andric
VisitInitListExpr(InitListExpr * E)18010b57cec5SDimitry Andric Value *ScalarExprEmitter::VisitInitListExpr(InitListExpr *E) {
18020b57cec5SDimitry Andric bool Ignore = TestAndClearIgnoreResultAssign();
18030b57cec5SDimitry Andric (void)Ignore;
18040b57cec5SDimitry Andric assert (Ignore == false && "init list ignored");
18050b57cec5SDimitry Andric unsigned NumInitElements = E->getNumInits();
18060b57cec5SDimitry Andric
18070b57cec5SDimitry Andric if (E->hadArrayRangeDesignator())
18080b57cec5SDimitry Andric CGF.ErrorUnsupported(E, "GNU array range designator extension");
18090b57cec5SDimitry Andric
18100b57cec5SDimitry Andric llvm::VectorType *VType =
18110b57cec5SDimitry Andric dyn_cast<llvm::VectorType>(ConvertType(E->getType()));
18120b57cec5SDimitry Andric
18130b57cec5SDimitry Andric if (!VType) {
18140b57cec5SDimitry Andric if (NumInitElements == 0) {
18150b57cec5SDimitry Andric // C++11 value-initialization for the scalar.
18160b57cec5SDimitry Andric return EmitNullValue(E->getType());
18170b57cec5SDimitry Andric }
18180b57cec5SDimitry Andric // We have a scalar in braces. Just use the first element.
18190b57cec5SDimitry Andric return Visit(E->getInit(0));
18200b57cec5SDimitry Andric }
18210b57cec5SDimitry Andric
1822af732203SDimitry Andric unsigned ResElts = cast<llvm::FixedVectorType>(VType)->getNumElements();
18230b57cec5SDimitry Andric
18240b57cec5SDimitry Andric // Loop over initializers collecting the Value for each, and remembering
18250b57cec5SDimitry Andric // whether the source was swizzle (ExtVectorElementExpr). This will allow
18260b57cec5SDimitry Andric // us to fold the shuffle for the swizzle into the shuffle for the vector
18270b57cec5SDimitry Andric // initializer, since LLVM optimizers generally do not want to touch
18280b57cec5SDimitry Andric // shuffles.
18290b57cec5SDimitry Andric unsigned CurIdx = 0;
18300b57cec5SDimitry Andric bool VIsUndefShuffle = false;
18310b57cec5SDimitry Andric llvm::Value *V = llvm::UndefValue::get(VType);
18320b57cec5SDimitry Andric for (unsigned i = 0; i != NumInitElements; ++i) {
18330b57cec5SDimitry Andric Expr *IE = E->getInit(i);
18340b57cec5SDimitry Andric Value *Init = Visit(IE);
18355ffd83dbSDimitry Andric SmallVector<int, 16> Args;
18360b57cec5SDimitry Andric
18370b57cec5SDimitry Andric llvm::VectorType *VVT = dyn_cast<llvm::VectorType>(Init->getType());
18380b57cec5SDimitry Andric
18390b57cec5SDimitry Andric // Handle scalar elements. If the scalar initializer is actually one
18400b57cec5SDimitry Andric // element of a different vector of the same width, use shuffle instead of
18410b57cec5SDimitry Andric // extract+insert.
18420b57cec5SDimitry Andric if (!VVT) {
18430b57cec5SDimitry Andric if (isa<ExtVectorElementExpr>(IE)) {
18440b57cec5SDimitry Andric llvm::ExtractElementInst *EI = cast<llvm::ExtractElementInst>(Init);
18450b57cec5SDimitry Andric
1846af732203SDimitry Andric if (cast<llvm::FixedVectorType>(EI->getVectorOperandType())
1847af732203SDimitry Andric ->getNumElements() == ResElts) {
18480b57cec5SDimitry Andric llvm::ConstantInt *C = cast<llvm::ConstantInt>(EI->getIndexOperand());
18490b57cec5SDimitry Andric Value *LHS = nullptr, *RHS = nullptr;
18500b57cec5SDimitry Andric if (CurIdx == 0) {
18510b57cec5SDimitry Andric // insert into undef -> shuffle (src, undef)
18520b57cec5SDimitry Andric // shufflemask must use an i32
18530b57cec5SDimitry Andric Args.push_back(getAsInt32(C, CGF.Int32Ty));
18545ffd83dbSDimitry Andric Args.resize(ResElts, -1);
18550b57cec5SDimitry Andric
18560b57cec5SDimitry Andric LHS = EI->getVectorOperand();
18570b57cec5SDimitry Andric RHS = V;
18580b57cec5SDimitry Andric VIsUndefShuffle = true;
18590b57cec5SDimitry Andric } else if (VIsUndefShuffle) {
18600b57cec5SDimitry Andric // insert into undefshuffle && size match -> shuffle (v, src)
18610b57cec5SDimitry Andric llvm::ShuffleVectorInst *SVV = cast<llvm::ShuffleVectorInst>(V);
18620b57cec5SDimitry Andric for (unsigned j = 0; j != CurIdx; ++j)
18635ffd83dbSDimitry Andric Args.push_back(getMaskElt(SVV, j, 0));
18645ffd83dbSDimitry Andric Args.push_back(ResElts + C->getZExtValue());
18655ffd83dbSDimitry Andric Args.resize(ResElts, -1);
18660b57cec5SDimitry Andric
18670b57cec5SDimitry Andric LHS = cast<llvm::ShuffleVectorInst>(V)->getOperand(0);
18680b57cec5SDimitry Andric RHS = EI->getVectorOperand();
18690b57cec5SDimitry Andric VIsUndefShuffle = false;
18700b57cec5SDimitry Andric }
18710b57cec5SDimitry Andric if (!Args.empty()) {
18725ffd83dbSDimitry Andric V = Builder.CreateShuffleVector(LHS, RHS, Args);
18730b57cec5SDimitry Andric ++CurIdx;
18740b57cec5SDimitry Andric continue;
18750b57cec5SDimitry Andric }
18760b57cec5SDimitry Andric }
18770b57cec5SDimitry Andric }
18780b57cec5SDimitry Andric V = Builder.CreateInsertElement(V, Init, Builder.getInt32(CurIdx),
18790b57cec5SDimitry Andric "vecinit");
18800b57cec5SDimitry Andric VIsUndefShuffle = false;
18810b57cec5SDimitry Andric ++CurIdx;
18820b57cec5SDimitry Andric continue;
18830b57cec5SDimitry Andric }
18840b57cec5SDimitry Andric
1885af732203SDimitry Andric unsigned InitElts = cast<llvm::FixedVectorType>(VVT)->getNumElements();
18860b57cec5SDimitry Andric
18870b57cec5SDimitry Andric // If the initializer is an ExtVecEltExpr (a swizzle), and the swizzle's
18880b57cec5SDimitry Andric // input is the same width as the vector being constructed, generate an
18890b57cec5SDimitry Andric // optimized shuffle of the swizzle input into the result.
18900b57cec5SDimitry Andric unsigned Offset = (CurIdx == 0) ? 0 : ResElts;
18910b57cec5SDimitry Andric if (isa<ExtVectorElementExpr>(IE)) {
18920b57cec5SDimitry Andric llvm::ShuffleVectorInst *SVI = cast<llvm::ShuffleVectorInst>(Init);
18930b57cec5SDimitry Andric Value *SVOp = SVI->getOperand(0);
1894af732203SDimitry Andric auto *OpTy = cast<llvm::FixedVectorType>(SVOp->getType());
18950b57cec5SDimitry Andric
18960b57cec5SDimitry Andric if (OpTy->getNumElements() == ResElts) {
18970b57cec5SDimitry Andric for (unsigned j = 0; j != CurIdx; ++j) {
18980b57cec5SDimitry Andric // If the current vector initializer is a shuffle with undef, merge
18990b57cec5SDimitry Andric // this shuffle directly into it.
19000b57cec5SDimitry Andric if (VIsUndefShuffle) {
19015ffd83dbSDimitry Andric Args.push_back(getMaskElt(cast<llvm::ShuffleVectorInst>(V), j, 0));
19020b57cec5SDimitry Andric } else {
19035ffd83dbSDimitry Andric Args.push_back(j);
19040b57cec5SDimitry Andric }
19050b57cec5SDimitry Andric }
19060b57cec5SDimitry Andric for (unsigned j = 0, je = InitElts; j != je; ++j)
19075ffd83dbSDimitry Andric Args.push_back(getMaskElt(SVI, j, Offset));
19085ffd83dbSDimitry Andric Args.resize(ResElts, -1);
19090b57cec5SDimitry Andric
19100b57cec5SDimitry Andric if (VIsUndefShuffle)
19110b57cec5SDimitry Andric V = cast<llvm::ShuffleVectorInst>(V)->getOperand(0);
19120b57cec5SDimitry Andric
19130b57cec5SDimitry Andric Init = SVOp;
19140b57cec5SDimitry Andric }
19150b57cec5SDimitry Andric }
19160b57cec5SDimitry Andric
19170b57cec5SDimitry Andric // Extend init to result vector length, and then shuffle its contribution
19180b57cec5SDimitry Andric // to the vector initializer into V.
19190b57cec5SDimitry Andric if (Args.empty()) {
19200b57cec5SDimitry Andric for (unsigned j = 0; j != InitElts; ++j)
19215ffd83dbSDimitry Andric Args.push_back(j);
19225ffd83dbSDimitry Andric Args.resize(ResElts, -1);
1923af732203SDimitry Andric Init = Builder.CreateShuffleVector(Init, Args, "vext");
19240b57cec5SDimitry Andric
19250b57cec5SDimitry Andric Args.clear();
19260b57cec5SDimitry Andric for (unsigned j = 0; j != CurIdx; ++j)
19275ffd83dbSDimitry Andric Args.push_back(j);
19280b57cec5SDimitry Andric for (unsigned j = 0; j != InitElts; ++j)
19295ffd83dbSDimitry Andric Args.push_back(j + Offset);
19305ffd83dbSDimitry Andric Args.resize(ResElts, -1);
19310b57cec5SDimitry Andric }
19320b57cec5SDimitry Andric
19330b57cec5SDimitry Andric // If V is undef, make sure it ends up on the RHS of the shuffle to aid
19340b57cec5SDimitry Andric // merging subsequent shuffles into this one.
19350b57cec5SDimitry Andric if (CurIdx == 0)
19360b57cec5SDimitry Andric std::swap(V, Init);
19375ffd83dbSDimitry Andric V = Builder.CreateShuffleVector(V, Init, Args, "vecinit");
19380b57cec5SDimitry Andric VIsUndefShuffle = isa<llvm::UndefValue>(Init);
19390b57cec5SDimitry Andric CurIdx += InitElts;
19400b57cec5SDimitry Andric }
19410b57cec5SDimitry Andric
19420b57cec5SDimitry Andric // FIXME: evaluate codegen vs. shuffling against constant null vector.
19430b57cec5SDimitry Andric // Emit remaining default initializers.
19440b57cec5SDimitry Andric llvm::Type *EltTy = VType->getElementType();
19450b57cec5SDimitry Andric
19460b57cec5SDimitry Andric // Emit remaining default initializers
19470b57cec5SDimitry Andric for (/* Do not initialize i*/; CurIdx < ResElts; ++CurIdx) {
19480b57cec5SDimitry Andric Value *Idx = Builder.getInt32(CurIdx);
19490b57cec5SDimitry Andric llvm::Value *Init = llvm::Constant::getNullValue(EltTy);
19500b57cec5SDimitry Andric V = Builder.CreateInsertElement(V, Init, Idx, "vecinit");
19510b57cec5SDimitry Andric }
19520b57cec5SDimitry Andric return V;
19530b57cec5SDimitry Andric }
19540b57cec5SDimitry Andric
ShouldNullCheckClassCastValue(const CastExpr * CE)19550b57cec5SDimitry Andric bool CodeGenFunction::ShouldNullCheckClassCastValue(const CastExpr *CE) {
19560b57cec5SDimitry Andric const Expr *E = CE->getSubExpr();
19570b57cec5SDimitry Andric
19580b57cec5SDimitry Andric if (CE->getCastKind() == CK_UncheckedDerivedToBase)
19590b57cec5SDimitry Andric return false;
19600b57cec5SDimitry Andric
19610b57cec5SDimitry Andric if (isa<CXXThisExpr>(E->IgnoreParens())) {
19620b57cec5SDimitry Andric // We always assume that 'this' is never null.
19630b57cec5SDimitry Andric return false;
19640b57cec5SDimitry Andric }
19650b57cec5SDimitry Andric
19660b57cec5SDimitry Andric if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(CE)) {
19670b57cec5SDimitry Andric // And that glvalue casts are never null.
1968*5f7ddb14SDimitry Andric if (ICE->isGLValue())
19690b57cec5SDimitry Andric return false;
19700b57cec5SDimitry Andric }
19710b57cec5SDimitry Andric
19720b57cec5SDimitry Andric return true;
19730b57cec5SDimitry Andric }
19740b57cec5SDimitry Andric
19750b57cec5SDimitry Andric // VisitCastExpr - Emit code for an explicit or implicit cast. Implicit casts
19760b57cec5SDimitry Andric // have to handle a more broad range of conversions than explicit casts, as they
19770b57cec5SDimitry Andric // handle things like function to ptr-to-function decay etc.
VisitCastExpr(CastExpr * CE)19780b57cec5SDimitry Andric Value *ScalarExprEmitter::VisitCastExpr(CastExpr *CE) {
19790b57cec5SDimitry Andric Expr *E = CE->getSubExpr();
19800b57cec5SDimitry Andric QualType DestTy = CE->getType();
19810b57cec5SDimitry Andric CastKind Kind = CE->getCastKind();
19820b57cec5SDimitry Andric
19830b57cec5SDimitry Andric // These cases are generally not written to ignore the result of
19840b57cec5SDimitry Andric // evaluating their sub-expressions, so we clear this now.
19850b57cec5SDimitry Andric bool Ignored = TestAndClearIgnoreResultAssign();
19860b57cec5SDimitry Andric
19870b57cec5SDimitry Andric // Since almost all cast kinds apply to scalars, this switch doesn't have
19880b57cec5SDimitry Andric // a default case, so the compiler will warn on a missing case. The cases
19890b57cec5SDimitry Andric // are in the same order as in the CastKind enum.
19900b57cec5SDimitry Andric switch (Kind) {
19910b57cec5SDimitry Andric case CK_Dependent: llvm_unreachable("dependent cast kind in IR gen!");
19920b57cec5SDimitry Andric case CK_BuiltinFnToFnPtr:
19930b57cec5SDimitry Andric llvm_unreachable("builtin functions are handled elsewhere");
19940b57cec5SDimitry Andric
19950b57cec5SDimitry Andric case CK_LValueBitCast:
19960b57cec5SDimitry Andric case CK_ObjCObjectLValueCast: {
1997480093f4SDimitry Andric Address Addr = EmitLValue(E).getAddress(CGF);
19980b57cec5SDimitry Andric Addr = Builder.CreateElementBitCast(Addr, CGF.ConvertTypeForMem(DestTy));
19990b57cec5SDimitry Andric LValue LV = CGF.MakeAddrLValue(Addr, DestTy);
20000b57cec5SDimitry Andric return EmitLoadOfLValue(LV, CE->getExprLoc());
20010b57cec5SDimitry Andric }
20020b57cec5SDimitry Andric
20030b57cec5SDimitry Andric case CK_LValueToRValueBitCast: {
20040b57cec5SDimitry Andric LValue SourceLVal = CGF.EmitLValue(E);
2005480093f4SDimitry Andric Address Addr = Builder.CreateElementBitCast(SourceLVal.getAddress(CGF),
20060b57cec5SDimitry Andric CGF.ConvertTypeForMem(DestTy));
20070b57cec5SDimitry Andric LValue DestLV = CGF.MakeAddrLValue(Addr, DestTy);
20080b57cec5SDimitry Andric DestLV.setTBAAInfo(TBAAAccessInfo::getMayAliasInfo());
20090b57cec5SDimitry Andric return EmitLoadOfLValue(DestLV, CE->getExprLoc());
20100b57cec5SDimitry Andric }
20110b57cec5SDimitry Andric
20120b57cec5SDimitry Andric case CK_CPointerToObjCPointerCast:
20130b57cec5SDimitry Andric case CK_BlockPointerToObjCPointerCast:
20140b57cec5SDimitry Andric case CK_AnyPointerToBlockPointerCast:
20150b57cec5SDimitry Andric case CK_BitCast: {
20160b57cec5SDimitry Andric Value *Src = Visit(const_cast<Expr*>(E));
20170b57cec5SDimitry Andric llvm::Type *SrcTy = Src->getType();
20180b57cec5SDimitry Andric llvm::Type *DstTy = ConvertType(DestTy);
20190b57cec5SDimitry Andric if (SrcTy->isPtrOrPtrVectorTy() && DstTy->isPtrOrPtrVectorTy() &&
20200b57cec5SDimitry Andric SrcTy->getPointerAddressSpace() != DstTy->getPointerAddressSpace()) {
20210b57cec5SDimitry Andric llvm_unreachable("wrong cast for pointers in different address spaces"
20220b57cec5SDimitry Andric "(must be an address space cast)!");
20230b57cec5SDimitry Andric }
20240b57cec5SDimitry Andric
20250b57cec5SDimitry Andric if (CGF.SanOpts.has(SanitizerKind::CFIUnrelatedCast)) {
20260b57cec5SDimitry Andric if (auto PT = DestTy->getAs<PointerType>())
20270b57cec5SDimitry Andric CGF.EmitVTablePtrCheckForCast(PT->getPointeeType(), Src,
20280b57cec5SDimitry Andric /*MayBeNull=*/true,
20290b57cec5SDimitry Andric CodeGenFunction::CFITCK_UnrelatedCast,
20300b57cec5SDimitry Andric CE->getBeginLoc());
20310b57cec5SDimitry Andric }
20320b57cec5SDimitry Andric
20330b57cec5SDimitry Andric if (CGF.CGM.getCodeGenOpts().StrictVTablePointers) {
20340b57cec5SDimitry Andric const QualType SrcType = E->getType();
20350b57cec5SDimitry Andric
20360b57cec5SDimitry Andric if (SrcType.mayBeNotDynamicClass() && DestTy.mayBeDynamicClass()) {
20370b57cec5SDimitry Andric // Casting to pointer that could carry dynamic information (provided by
20380b57cec5SDimitry Andric // invariant.group) requires launder.
20390b57cec5SDimitry Andric Src = Builder.CreateLaunderInvariantGroup(Src);
20400b57cec5SDimitry Andric } else if (SrcType.mayBeDynamicClass() && DestTy.mayBeNotDynamicClass()) {
20410b57cec5SDimitry Andric // Casting to pointer that does not carry dynamic information (provided
20420b57cec5SDimitry Andric // by invariant.group) requires stripping it. Note that we don't do it
20430b57cec5SDimitry Andric // if the source could not be dynamic type and destination could be
20440b57cec5SDimitry Andric // dynamic because dynamic information is already laundered. It is
20450b57cec5SDimitry Andric // because launder(strip(src)) == launder(src), so there is no need to
20460b57cec5SDimitry Andric // add extra strip before launder.
20470b57cec5SDimitry Andric Src = Builder.CreateStripInvariantGroup(Src);
20480b57cec5SDimitry Andric }
20490b57cec5SDimitry Andric }
20500b57cec5SDimitry Andric
20515ffd83dbSDimitry Andric // Update heapallocsite metadata when there is an explicit pointer cast.
20525ffd83dbSDimitry Andric if (auto *CI = dyn_cast<llvm::CallBase>(Src)) {
20535ffd83dbSDimitry Andric if (CI->getMetadata("heapallocsite") && isa<ExplicitCastExpr>(CE)) {
20545ffd83dbSDimitry Andric QualType PointeeType = DestTy->getPointeeType();
20555ffd83dbSDimitry Andric if (!PointeeType.isNull())
20565ffd83dbSDimitry Andric CGF.getDebugInfo()->addHeapAllocSiteMetadata(CI, PointeeType,
20575ffd83dbSDimitry Andric CE->getExprLoc());
20585ffd83dbSDimitry Andric }
20595ffd83dbSDimitry Andric }
20600b57cec5SDimitry Andric
2061af732203SDimitry Andric // If Src is a fixed vector and Dst is a scalable vector, and both have the
2062af732203SDimitry Andric // same element type, use the llvm.experimental.vector.insert intrinsic to
2063af732203SDimitry Andric // perform the bitcast.
2064af732203SDimitry Andric if (const auto *FixedSrc = dyn_cast<llvm::FixedVectorType>(SrcTy)) {
2065af732203SDimitry Andric if (const auto *ScalableDst = dyn_cast<llvm::ScalableVectorType>(DstTy)) {
2066af732203SDimitry Andric if (FixedSrc->getElementType() == ScalableDst->getElementType()) {
2067af732203SDimitry Andric llvm::Value *UndefVec = llvm::UndefValue::get(DstTy);
2068af732203SDimitry Andric llvm::Value *Zero = llvm::Constant::getNullValue(CGF.CGM.Int64Ty);
2069af732203SDimitry Andric return Builder.CreateInsertVector(DstTy, UndefVec, Src, Zero,
2070af732203SDimitry Andric "castScalableSve");
2071af732203SDimitry Andric }
2072af732203SDimitry Andric }
2073af732203SDimitry Andric }
2074af732203SDimitry Andric
2075af732203SDimitry Andric // If Src is a scalable vector and Dst is a fixed vector, and both have the
2076af732203SDimitry Andric // same element type, use the llvm.experimental.vector.extract intrinsic to
2077af732203SDimitry Andric // perform the bitcast.
2078af732203SDimitry Andric if (const auto *ScalableSrc = dyn_cast<llvm::ScalableVectorType>(SrcTy)) {
2079af732203SDimitry Andric if (const auto *FixedDst = dyn_cast<llvm::FixedVectorType>(DstTy)) {
2080af732203SDimitry Andric if (ScalableSrc->getElementType() == FixedDst->getElementType()) {
2081af732203SDimitry Andric llvm::Value *Zero = llvm::Constant::getNullValue(CGF.CGM.Int64Ty);
2082af732203SDimitry Andric return Builder.CreateExtractVector(DstTy, Src, Zero, "castFixedSve");
2083af732203SDimitry Andric }
2084af732203SDimitry Andric }
2085af732203SDimitry Andric }
2086af732203SDimitry Andric
2087af732203SDimitry Andric // Perform VLAT <-> VLST bitcast through memory.
2088af732203SDimitry Andric // TODO: since the llvm.experimental.vector.{insert,extract} intrinsics
2089af732203SDimitry Andric // require the element types of the vectors to be the same, we
2090af732203SDimitry Andric // need to keep this around for casting between predicates, or more
2091af732203SDimitry Andric // generally for bitcasts between VLAT <-> VLST where the element
2092af732203SDimitry Andric // types of the vectors are not the same, until we figure out a better
2093af732203SDimitry Andric // way of doing these casts.
2094af732203SDimitry Andric if ((isa<llvm::FixedVectorType>(SrcTy) &&
2095af732203SDimitry Andric isa<llvm::ScalableVectorType>(DstTy)) ||
2096af732203SDimitry Andric (isa<llvm::ScalableVectorType>(SrcTy) &&
2097af732203SDimitry Andric isa<llvm::FixedVectorType>(DstTy))) {
2098*5f7ddb14SDimitry Andric Address Addr = CGF.CreateDefaultAlignTempAlloca(SrcTy, "saved-value");
2099*5f7ddb14SDimitry Andric LValue LV = CGF.MakeAddrLValue(Addr, E->getType());
2100af732203SDimitry Andric CGF.EmitStoreOfScalar(Src, LV);
2101af732203SDimitry Andric Addr = Builder.CreateElementBitCast(Addr, CGF.ConvertTypeForMem(DestTy),
2102af732203SDimitry Andric "castFixedSve");
2103af732203SDimitry Andric LValue DestLV = CGF.MakeAddrLValue(Addr, DestTy);
2104af732203SDimitry Andric DestLV.setTBAAInfo(TBAAAccessInfo::getMayAliasInfo());
2105af732203SDimitry Andric return EmitLoadOfLValue(DestLV, CE->getExprLoc());
2106af732203SDimitry Andric }
2107af732203SDimitry Andric
21080b57cec5SDimitry Andric return Builder.CreateBitCast(Src, DstTy);
21090b57cec5SDimitry Andric }
21100b57cec5SDimitry Andric case CK_AddressSpaceConversion: {
21110b57cec5SDimitry Andric Expr::EvalResult Result;
21120b57cec5SDimitry Andric if (E->EvaluateAsRValue(Result, CGF.getContext()) &&
21130b57cec5SDimitry Andric Result.Val.isNullPointer()) {
21140b57cec5SDimitry Andric // If E has side effect, it is emitted even if its final result is a
21150b57cec5SDimitry Andric // null pointer. In that case, a DCE pass should be able to
21160b57cec5SDimitry Andric // eliminate the useless instructions emitted during translating E.
21170b57cec5SDimitry Andric if (Result.HasSideEffects)
21180b57cec5SDimitry Andric Visit(E);
21190b57cec5SDimitry Andric return CGF.CGM.getNullPointer(cast<llvm::PointerType>(
21200b57cec5SDimitry Andric ConvertType(DestTy)), DestTy);
21210b57cec5SDimitry Andric }
21220b57cec5SDimitry Andric // Since target may map different address spaces in AST to the same address
21230b57cec5SDimitry Andric // space, an address space conversion may end up as a bitcast.
21240b57cec5SDimitry Andric return CGF.CGM.getTargetCodeGenInfo().performAddrSpaceCast(
21250b57cec5SDimitry Andric CGF, Visit(E), E->getType()->getPointeeType().getAddressSpace(),
21260b57cec5SDimitry Andric DestTy->getPointeeType().getAddressSpace(), ConvertType(DestTy));
21270b57cec5SDimitry Andric }
21280b57cec5SDimitry Andric case CK_AtomicToNonAtomic:
21290b57cec5SDimitry Andric case CK_NonAtomicToAtomic:
21300b57cec5SDimitry Andric case CK_NoOp:
21310b57cec5SDimitry Andric case CK_UserDefinedConversion:
21320b57cec5SDimitry Andric return Visit(const_cast<Expr*>(E));
21330b57cec5SDimitry Andric
21340b57cec5SDimitry Andric case CK_BaseToDerived: {
21350b57cec5SDimitry Andric const CXXRecordDecl *DerivedClassDecl = DestTy->getPointeeCXXRecordDecl();
21360b57cec5SDimitry Andric assert(DerivedClassDecl && "BaseToDerived arg isn't a C++ object pointer!");
21370b57cec5SDimitry Andric
21380b57cec5SDimitry Andric Address Base = CGF.EmitPointerWithAlignment(E);
21390b57cec5SDimitry Andric Address Derived =
21400b57cec5SDimitry Andric CGF.GetAddressOfDerivedClass(Base, DerivedClassDecl,
21410b57cec5SDimitry Andric CE->path_begin(), CE->path_end(),
21420b57cec5SDimitry Andric CGF.ShouldNullCheckClassCastValue(CE));
21430b57cec5SDimitry Andric
21440b57cec5SDimitry Andric // C++11 [expr.static.cast]p11: Behavior is undefined if a downcast is
21450b57cec5SDimitry Andric // performed and the object is not of the derived type.
21460b57cec5SDimitry Andric if (CGF.sanitizePerformTypeCheck())
21470b57cec5SDimitry Andric CGF.EmitTypeCheck(CodeGenFunction::TCK_DowncastPointer, CE->getExprLoc(),
21480b57cec5SDimitry Andric Derived.getPointer(), DestTy->getPointeeType());
21490b57cec5SDimitry Andric
21500b57cec5SDimitry Andric if (CGF.SanOpts.has(SanitizerKind::CFIDerivedCast))
21510b57cec5SDimitry Andric CGF.EmitVTablePtrCheckForCast(
21520b57cec5SDimitry Andric DestTy->getPointeeType(), Derived.getPointer(),
21530b57cec5SDimitry Andric /*MayBeNull=*/true, CodeGenFunction::CFITCK_DerivedCast,
21540b57cec5SDimitry Andric CE->getBeginLoc());
21550b57cec5SDimitry Andric
21560b57cec5SDimitry Andric return Derived.getPointer();
21570b57cec5SDimitry Andric }
21580b57cec5SDimitry Andric case CK_UncheckedDerivedToBase:
21590b57cec5SDimitry Andric case CK_DerivedToBase: {
21600b57cec5SDimitry Andric // The EmitPointerWithAlignment path does this fine; just discard
21610b57cec5SDimitry Andric // the alignment.
21620b57cec5SDimitry Andric return CGF.EmitPointerWithAlignment(CE).getPointer();
21630b57cec5SDimitry Andric }
21640b57cec5SDimitry Andric
21650b57cec5SDimitry Andric case CK_Dynamic: {
21660b57cec5SDimitry Andric Address V = CGF.EmitPointerWithAlignment(E);
21670b57cec5SDimitry Andric const CXXDynamicCastExpr *DCE = cast<CXXDynamicCastExpr>(CE);
21680b57cec5SDimitry Andric return CGF.EmitDynamicCast(V, DCE);
21690b57cec5SDimitry Andric }
21700b57cec5SDimitry Andric
21710b57cec5SDimitry Andric case CK_ArrayToPointerDecay:
21720b57cec5SDimitry Andric return CGF.EmitArrayToPointerDecay(E).getPointer();
21730b57cec5SDimitry Andric case CK_FunctionToPointerDecay:
2174480093f4SDimitry Andric return EmitLValue(E).getPointer(CGF);
21750b57cec5SDimitry Andric
21760b57cec5SDimitry Andric case CK_NullToPointer:
21770b57cec5SDimitry Andric if (MustVisitNullValue(E))
21780b57cec5SDimitry Andric CGF.EmitIgnoredExpr(E);
21790b57cec5SDimitry Andric
21800b57cec5SDimitry Andric return CGF.CGM.getNullPointer(cast<llvm::PointerType>(ConvertType(DestTy)),
21810b57cec5SDimitry Andric DestTy);
21820b57cec5SDimitry Andric
21830b57cec5SDimitry Andric case CK_NullToMemberPointer: {
21840b57cec5SDimitry Andric if (MustVisitNullValue(E))
21850b57cec5SDimitry Andric CGF.EmitIgnoredExpr(E);
21860b57cec5SDimitry Andric
21870b57cec5SDimitry Andric const MemberPointerType *MPT = CE->getType()->getAs<MemberPointerType>();
21880b57cec5SDimitry Andric return CGF.CGM.getCXXABI().EmitNullMemberPointer(MPT);
21890b57cec5SDimitry Andric }
21900b57cec5SDimitry Andric
21910b57cec5SDimitry Andric case CK_ReinterpretMemberPointer:
21920b57cec5SDimitry Andric case CK_BaseToDerivedMemberPointer:
21930b57cec5SDimitry Andric case CK_DerivedToBaseMemberPointer: {
21940b57cec5SDimitry Andric Value *Src = Visit(E);
21950b57cec5SDimitry Andric
21960b57cec5SDimitry Andric // Note that the AST doesn't distinguish between checked and
21970b57cec5SDimitry Andric // unchecked member pointer conversions, so we always have to
21980b57cec5SDimitry Andric // implement checked conversions here. This is inefficient when
21990b57cec5SDimitry Andric // actual control flow may be required in order to perform the
22000b57cec5SDimitry Andric // check, which it is for data member pointers (but not member
22010b57cec5SDimitry Andric // function pointers on Itanium and ARM).
22020b57cec5SDimitry Andric return CGF.CGM.getCXXABI().EmitMemberPointerConversion(CGF, CE, Src);
22030b57cec5SDimitry Andric }
22040b57cec5SDimitry Andric
22050b57cec5SDimitry Andric case CK_ARCProduceObject:
22060b57cec5SDimitry Andric return CGF.EmitARCRetainScalarExpr(E);
22070b57cec5SDimitry Andric case CK_ARCConsumeObject:
22080b57cec5SDimitry Andric return CGF.EmitObjCConsumeObject(E->getType(), Visit(E));
22090b57cec5SDimitry Andric case CK_ARCReclaimReturnedObject:
22100b57cec5SDimitry Andric return CGF.EmitARCReclaimReturnedObject(E, /*allowUnsafe*/ Ignored);
22110b57cec5SDimitry Andric case CK_ARCExtendBlockObject:
22120b57cec5SDimitry Andric return CGF.EmitARCExtendBlockObject(E);
22130b57cec5SDimitry Andric
22140b57cec5SDimitry Andric case CK_CopyAndAutoreleaseBlockObject:
22150b57cec5SDimitry Andric return CGF.EmitBlockCopyAndAutorelease(Visit(E), E->getType());
22160b57cec5SDimitry Andric
22170b57cec5SDimitry Andric case CK_FloatingRealToComplex:
22180b57cec5SDimitry Andric case CK_FloatingComplexCast:
22190b57cec5SDimitry Andric case CK_IntegralRealToComplex:
22200b57cec5SDimitry Andric case CK_IntegralComplexCast:
22210b57cec5SDimitry Andric case CK_IntegralComplexToFloatingComplex:
22220b57cec5SDimitry Andric case CK_FloatingComplexToIntegralComplex:
22230b57cec5SDimitry Andric case CK_ConstructorConversion:
22240b57cec5SDimitry Andric case CK_ToUnion:
22250b57cec5SDimitry Andric llvm_unreachable("scalar cast to non-scalar value");
22260b57cec5SDimitry Andric
22270b57cec5SDimitry Andric case CK_LValueToRValue:
22280b57cec5SDimitry Andric assert(CGF.getContext().hasSameUnqualifiedType(E->getType(), DestTy));
22290b57cec5SDimitry Andric assert(E->isGLValue() && "lvalue-to-rvalue applied to r-value!");
22300b57cec5SDimitry Andric return Visit(const_cast<Expr*>(E));
22310b57cec5SDimitry Andric
22320b57cec5SDimitry Andric case CK_IntegralToPointer: {
22330b57cec5SDimitry Andric Value *Src = Visit(const_cast<Expr*>(E));
22340b57cec5SDimitry Andric
22350b57cec5SDimitry Andric // First, convert to the correct width so that we control the kind of
22360b57cec5SDimitry Andric // extension.
22370b57cec5SDimitry Andric auto DestLLVMTy = ConvertType(DestTy);
22380b57cec5SDimitry Andric llvm::Type *MiddleTy = CGF.CGM.getDataLayout().getIntPtrType(DestLLVMTy);
22390b57cec5SDimitry Andric bool InputSigned = E->getType()->isSignedIntegerOrEnumerationType();
22400b57cec5SDimitry Andric llvm::Value* IntResult =
22410b57cec5SDimitry Andric Builder.CreateIntCast(Src, MiddleTy, InputSigned, "conv");
22420b57cec5SDimitry Andric
22430b57cec5SDimitry Andric auto *IntToPtr = Builder.CreateIntToPtr(IntResult, DestLLVMTy);
22440b57cec5SDimitry Andric
22450b57cec5SDimitry Andric if (CGF.CGM.getCodeGenOpts().StrictVTablePointers) {
22460b57cec5SDimitry Andric // Going from integer to pointer that could be dynamic requires reloading
22470b57cec5SDimitry Andric // dynamic information from invariant.group.
22480b57cec5SDimitry Andric if (DestTy.mayBeDynamicClass())
22490b57cec5SDimitry Andric IntToPtr = Builder.CreateLaunderInvariantGroup(IntToPtr);
22500b57cec5SDimitry Andric }
22510b57cec5SDimitry Andric return IntToPtr;
22520b57cec5SDimitry Andric }
22530b57cec5SDimitry Andric case CK_PointerToIntegral: {
22540b57cec5SDimitry Andric assert(!DestTy->isBooleanType() && "bool should use PointerToBool");
22550b57cec5SDimitry Andric auto *PtrExpr = Visit(E);
22560b57cec5SDimitry Andric
22570b57cec5SDimitry Andric if (CGF.CGM.getCodeGenOpts().StrictVTablePointers) {
22580b57cec5SDimitry Andric const QualType SrcType = E->getType();
22590b57cec5SDimitry Andric
22600b57cec5SDimitry Andric // Casting to integer requires stripping dynamic information as it does
22610b57cec5SDimitry Andric // not carries it.
22620b57cec5SDimitry Andric if (SrcType.mayBeDynamicClass())
22630b57cec5SDimitry Andric PtrExpr = Builder.CreateStripInvariantGroup(PtrExpr);
22640b57cec5SDimitry Andric }
22650b57cec5SDimitry Andric
22660b57cec5SDimitry Andric return Builder.CreatePtrToInt(PtrExpr, ConvertType(DestTy));
22670b57cec5SDimitry Andric }
22680b57cec5SDimitry Andric case CK_ToVoid: {
22690b57cec5SDimitry Andric CGF.EmitIgnoredExpr(E);
22700b57cec5SDimitry Andric return nullptr;
22710b57cec5SDimitry Andric }
2272*5f7ddb14SDimitry Andric case CK_MatrixCast: {
2273*5f7ddb14SDimitry Andric return EmitScalarConversion(Visit(E), E->getType(), DestTy,
2274*5f7ddb14SDimitry Andric CE->getExprLoc());
2275*5f7ddb14SDimitry Andric }
22760b57cec5SDimitry Andric case CK_VectorSplat: {
22770b57cec5SDimitry Andric llvm::Type *DstTy = ConvertType(DestTy);
22780b57cec5SDimitry Andric Value *Elt = Visit(const_cast<Expr*>(E));
22790b57cec5SDimitry Andric // Splat the element across to all elements
2280af732203SDimitry Andric unsigned NumElements = cast<llvm::FixedVectorType>(DstTy)->getNumElements();
22810b57cec5SDimitry Andric return Builder.CreateVectorSplat(NumElements, Elt, "splat");
22820b57cec5SDimitry Andric }
22830b57cec5SDimitry Andric
22840b57cec5SDimitry Andric case CK_FixedPointCast:
22850b57cec5SDimitry Andric return EmitScalarConversion(Visit(E), E->getType(), DestTy,
22860b57cec5SDimitry Andric CE->getExprLoc());
22870b57cec5SDimitry Andric
22880b57cec5SDimitry Andric case CK_FixedPointToBoolean:
22890b57cec5SDimitry Andric assert(E->getType()->isFixedPointType() &&
22900b57cec5SDimitry Andric "Expected src type to be fixed point type");
22910b57cec5SDimitry Andric assert(DestTy->isBooleanType() && "Expected dest type to be boolean type");
22920b57cec5SDimitry Andric return EmitScalarConversion(Visit(E), E->getType(), DestTy,
22930b57cec5SDimitry Andric CE->getExprLoc());
22940b57cec5SDimitry Andric
22950b57cec5SDimitry Andric case CK_FixedPointToIntegral:
22960b57cec5SDimitry Andric assert(E->getType()->isFixedPointType() &&
22970b57cec5SDimitry Andric "Expected src type to be fixed point type");
22980b57cec5SDimitry Andric assert(DestTy->isIntegerType() && "Expected dest type to be an integer");
22990b57cec5SDimitry Andric return EmitScalarConversion(Visit(E), E->getType(), DestTy,
23000b57cec5SDimitry Andric CE->getExprLoc());
23010b57cec5SDimitry Andric
23020b57cec5SDimitry Andric case CK_IntegralToFixedPoint:
23030b57cec5SDimitry Andric assert(E->getType()->isIntegerType() &&
23040b57cec5SDimitry Andric "Expected src type to be an integer");
23050b57cec5SDimitry Andric assert(DestTy->isFixedPointType() &&
23060b57cec5SDimitry Andric "Expected dest type to be fixed point type");
23070b57cec5SDimitry Andric return EmitScalarConversion(Visit(E), E->getType(), DestTy,
23080b57cec5SDimitry Andric CE->getExprLoc());
23090b57cec5SDimitry Andric
23100b57cec5SDimitry Andric case CK_IntegralCast: {
23110b57cec5SDimitry Andric ScalarConversionOpts Opts;
23120b57cec5SDimitry Andric if (auto *ICE = dyn_cast<ImplicitCastExpr>(CE)) {
23130b57cec5SDimitry Andric if (!ICE->isPartOfExplicitCast())
23140b57cec5SDimitry Andric Opts = ScalarConversionOpts(CGF.SanOpts);
23150b57cec5SDimitry Andric }
23160b57cec5SDimitry Andric return EmitScalarConversion(Visit(E), E->getType(), DestTy,
23170b57cec5SDimitry Andric CE->getExprLoc(), Opts);
23180b57cec5SDimitry Andric }
23190b57cec5SDimitry Andric case CK_IntegralToFloating:
23200b57cec5SDimitry Andric case CK_FloatingToIntegral:
23210b57cec5SDimitry Andric case CK_FloatingCast:
2322af732203SDimitry Andric case CK_FixedPointToFloating:
2323af732203SDimitry Andric case CK_FloatingToFixedPoint: {
2324af732203SDimitry Andric CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, CE);
23250b57cec5SDimitry Andric return EmitScalarConversion(Visit(E), E->getType(), DestTy,
23260b57cec5SDimitry Andric CE->getExprLoc());
2327af732203SDimitry Andric }
23280b57cec5SDimitry Andric case CK_BooleanToSignedIntegral: {
23290b57cec5SDimitry Andric ScalarConversionOpts Opts;
23300b57cec5SDimitry Andric Opts.TreatBooleanAsSigned = true;
23310b57cec5SDimitry Andric return EmitScalarConversion(Visit(E), E->getType(), DestTy,
23320b57cec5SDimitry Andric CE->getExprLoc(), Opts);
23330b57cec5SDimitry Andric }
23340b57cec5SDimitry Andric case CK_IntegralToBoolean:
23350b57cec5SDimitry Andric return EmitIntToBoolConversion(Visit(E));
23360b57cec5SDimitry Andric case CK_PointerToBoolean:
23370b57cec5SDimitry Andric return EmitPointerToBoolConversion(Visit(E), E->getType());
2338af732203SDimitry Andric case CK_FloatingToBoolean: {
2339af732203SDimitry Andric CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, CE);
23400b57cec5SDimitry Andric return EmitFloatToBoolConversion(Visit(E));
2341af732203SDimitry Andric }
23420b57cec5SDimitry Andric case CK_MemberPointerToBoolean: {
23430b57cec5SDimitry Andric llvm::Value *MemPtr = Visit(E);
23440b57cec5SDimitry Andric const MemberPointerType *MPT = E->getType()->getAs<MemberPointerType>();
23450b57cec5SDimitry Andric return CGF.CGM.getCXXABI().EmitMemberPointerIsNotNull(CGF, MemPtr, MPT);
23460b57cec5SDimitry Andric }
23470b57cec5SDimitry Andric
23480b57cec5SDimitry Andric case CK_FloatingComplexToReal:
23490b57cec5SDimitry Andric case CK_IntegralComplexToReal:
23500b57cec5SDimitry Andric return CGF.EmitComplexExpr(E, false, true).first;
23510b57cec5SDimitry Andric
23520b57cec5SDimitry Andric case CK_FloatingComplexToBoolean:
23530b57cec5SDimitry Andric case CK_IntegralComplexToBoolean: {
23540b57cec5SDimitry Andric CodeGenFunction::ComplexPairTy V = CGF.EmitComplexExpr(E);
23550b57cec5SDimitry Andric
23560b57cec5SDimitry Andric // TODO: kill this function off, inline appropriate case here
23570b57cec5SDimitry Andric return EmitComplexToScalarConversion(V, E->getType(), DestTy,
23580b57cec5SDimitry Andric CE->getExprLoc());
23590b57cec5SDimitry Andric }
23600b57cec5SDimitry Andric
23610b57cec5SDimitry Andric case CK_ZeroToOCLOpaqueType: {
23620b57cec5SDimitry Andric assert((DestTy->isEventT() || DestTy->isQueueT() ||
23630b57cec5SDimitry Andric DestTy->isOCLIntelSubgroupAVCType()) &&
23640b57cec5SDimitry Andric "CK_ZeroToOCLEvent cast on non-event type");
23650b57cec5SDimitry Andric return llvm::Constant::getNullValue(ConvertType(DestTy));
23660b57cec5SDimitry Andric }
23670b57cec5SDimitry Andric
23680b57cec5SDimitry Andric case CK_IntToOCLSampler:
23690b57cec5SDimitry Andric return CGF.CGM.createOpenCLIntToSamplerConversion(E, CGF);
23700b57cec5SDimitry Andric
23710b57cec5SDimitry Andric } // end of switch
23720b57cec5SDimitry Andric
23730b57cec5SDimitry Andric llvm_unreachable("unknown scalar cast");
23740b57cec5SDimitry Andric }
23750b57cec5SDimitry Andric
VisitStmtExpr(const StmtExpr * E)23760b57cec5SDimitry Andric Value *ScalarExprEmitter::VisitStmtExpr(const StmtExpr *E) {
23770b57cec5SDimitry Andric CodeGenFunction::StmtExprEvaluation eval(CGF);
23780b57cec5SDimitry Andric Address RetAlloca = CGF.EmitCompoundStmt(*E->getSubStmt(),
23790b57cec5SDimitry Andric !E->getType()->isVoidType());
23800b57cec5SDimitry Andric if (!RetAlloca.isValid())
23810b57cec5SDimitry Andric return nullptr;
23820b57cec5SDimitry Andric return CGF.EmitLoadOfScalar(CGF.MakeAddrLValue(RetAlloca, E->getType()),
23830b57cec5SDimitry Andric E->getExprLoc());
23840b57cec5SDimitry Andric }
23850b57cec5SDimitry Andric
VisitExprWithCleanups(ExprWithCleanups * E)23860b57cec5SDimitry Andric Value *ScalarExprEmitter::VisitExprWithCleanups(ExprWithCleanups *E) {
23870b57cec5SDimitry Andric CodeGenFunction::RunCleanupsScope Scope(CGF);
23880b57cec5SDimitry Andric Value *V = Visit(E->getSubExpr());
23890b57cec5SDimitry Andric // Defend against dominance problems caused by jumps out of expression
23900b57cec5SDimitry Andric // evaluation through the shared cleanup block.
23910b57cec5SDimitry Andric Scope.ForceCleanup({&V});
23920b57cec5SDimitry Andric return V;
23930b57cec5SDimitry Andric }
23940b57cec5SDimitry Andric
23950b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
23960b57cec5SDimitry Andric // Unary Operators
23970b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
23980b57cec5SDimitry Andric
createBinOpInfoFromIncDec(const UnaryOperator * E,llvm::Value * InVal,bool IsInc,FPOptions FPFeatures)23990b57cec5SDimitry Andric static BinOpInfo createBinOpInfoFromIncDec(const UnaryOperator *E,
24005ffd83dbSDimitry Andric llvm::Value *InVal, bool IsInc,
24015ffd83dbSDimitry Andric FPOptions FPFeatures) {
24020b57cec5SDimitry Andric BinOpInfo BinOp;
24030b57cec5SDimitry Andric BinOp.LHS = InVal;
24040b57cec5SDimitry Andric BinOp.RHS = llvm::ConstantInt::get(InVal->getType(), 1, false);
24050b57cec5SDimitry Andric BinOp.Ty = E->getType();
24060b57cec5SDimitry Andric BinOp.Opcode = IsInc ? BO_Add : BO_Sub;
24075ffd83dbSDimitry Andric BinOp.FPFeatures = FPFeatures;
24080b57cec5SDimitry Andric BinOp.E = E;
24090b57cec5SDimitry Andric return BinOp;
24100b57cec5SDimitry Andric }
24110b57cec5SDimitry Andric
EmitIncDecConsiderOverflowBehavior(const UnaryOperator * E,llvm::Value * InVal,bool IsInc)24120b57cec5SDimitry Andric llvm::Value *ScalarExprEmitter::EmitIncDecConsiderOverflowBehavior(
24130b57cec5SDimitry Andric const UnaryOperator *E, llvm::Value *InVal, bool IsInc) {
24140b57cec5SDimitry Andric llvm::Value *Amount =
24150b57cec5SDimitry Andric llvm::ConstantInt::get(InVal->getType(), IsInc ? 1 : -1, true);
24160b57cec5SDimitry Andric StringRef Name = IsInc ? "inc" : "dec";
24170b57cec5SDimitry Andric switch (CGF.getLangOpts().getSignedOverflowBehavior()) {
24180b57cec5SDimitry Andric case LangOptions::SOB_Defined:
24190b57cec5SDimitry Andric return Builder.CreateAdd(InVal, Amount, Name);
24200b57cec5SDimitry Andric case LangOptions::SOB_Undefined:
24210b57cec5SDimitry Andric if (!CGF.SanOpts.has(SanitizerKind::SignedIntegerOverflow))
24220b57cec5SDimitry Andric return Builder.CreateNSWAdd(InVal, Amount, Name);
24230b57cec5SDimitry Andric LLVM_FALLTHROUGH;
24240b57cec5SDimitry Andric case LangOptions::SOB_Trapping:
24250b57cec5SDimitry Andric if (!E->canOverflow())
24260b57cec5SDimitry Andric return Builder.CreateNSWAdd(InVal, Amount, Name);
24275ffd83dbSDimitry Andric return EmitOverflowCheckedBinOp(createBinOpInfoFromIncDec(
24285ffd83dbSDimitry Andric E, InVal, IsInc, E->getFPFeaturesInEffect(CGF.getLangOpts())));
24290b57cec5SDimitry Andric }
24300b57cec5SDimitry Andric llvm_unreachable("Unknown SignedOverflowBehaviorTy");
24310b57cec5SDimitry Andric }
24320b57cec5SDimitry Andric
2433480093f4SDimitry Andric namespace {
2434480093f4SDimitry Andric /// Handles check and update for lastprivate conditional variables.
2435480093f4SDimitry Andric class OMPLastprivateConditionalUpdateRAII {
2436480093f4SDimitry Andric private:
2437480093f4SDimitry Andric CodeGenFunction &CGF;
2438480093f4SDimitry Andric const UnaryOperator *E;
2439480093f4SDimitry Andric
2440480093f4SDimitry Andric public:
OMPLastprivateConditionalUpdateRAII(CodeGenFunction & CGF,const UnaryOperator * E)2441480093f4SDimitry Andric OMPLastprivateConditionalUpdateRAII(CodeGenFunction &CGF,
2442480093f4SDimitry Andric const UnaryOperator *E)
2443480093f4SDimitry Andric : CGF(CGF), E(E) {}
~OMPLastprivateConditionalUpdateRAII()2444480093f4SDimitry Andric ~OMPLastprivateConditionalUpdateRAII() {
2445480093f4SDimitry Andric if (CGF.getLangOpts().OpenMP)
2446480093f4SDimitry Andric CGF.CGM.getOpenMPRuntime().checkAndEmitLastprivateConditional(
2447480093f4SDimitry Andric CGF, E->getSubExpr());
2448480093f4SDimitry Andric }
2449480093f4SDimitry Andric };
2450480093f4SDimitry Andric } // namespace
2451480093f4SDimitry Andric
24520b57cec5SDimitry Andric llvm::Value *
EmitScalarPrePostIncDec(const UnaryOperator * E,LValue LV,bool isInc,bool isPre)24530b57cec5SDimitry Andric ScalarExprEmitter::EmitScalarPrePostIncDec(const UnaryOperator *E, LValue LV,
24540b57cec5SDimitry Andric bool isInc, bool isPre) {
2455480093f4SDimitry Andric OMPLastprivateConditionalUpdateRAII OMPRegion(CGF, E);
24560b57cec5SDimitry Andric QualType type = E->getSubExpr()->getType();
24570b57cec5SDimitry Andric llvm::PHINode *atomicPHI = nullptr;
24580b57cec5SDimitry Andric llvm::Value *value;
24590b57cec5SDimitry Andric llvm::Value *input;
24600b57cec5SDimitry Andric
24610b57cec5SDimitry Andric int amount = (isInc ? 1 : -1);
24620b57cec5SDimitry Andric bool isSubtraction = !isInc;
24630b57cec5SDimitry Andric
24640b57cec5SDimitry Andric if (const AtomicType *atomicTy = type->getAs<AtomicType>()) {
24650b57cec5SDimitry Andric type = atomicTy->getValueType();
24660b57cec5SDimitry Andric if (isInc && type->isBooleanType()) {
24670b57cec5SDimitry Andric llvm::Value *True = CGF.EmitToMemory(Builder.getTrue(), type);
24680b57cec5SDimitry Andric if (isPre) {
2469480093f4SDimitry Andric Builder.CreateStore(True, LV.getAddress(CGF), LV.isVolatileQualified())
24700b57cec5SDimitry Andric ->setAtomic(llvm::AtomicOrdering::SequentiallyConsistent);
24710b57cec5SDimitry Andric return Builder.getTrue();
24720b57cec5SDimitry Andric }
24730b57cec5SDimitry Andric // For atomic bool increment, we just store true and return it for
24740b57cec5SDimitry Andric // preincrement, do an atomic swap with true for postincrement
24750b57cec5SDimitry Andric return Builder.CreateAtomicRMW(
2476480093f4SDimitry Andric llvm::AtomicRMWInst::Xchg, LV.getPointer(CGF), True,
24770b57cec5SDimitry Andric llvm::AtomicOrdering::SequentiallyConsistent);
24780b57cec5SDimitry Andric }
24790b57cec5SDimitry Andric // Special case for atomic increment / decrement on integers, emit
24800b57cec5SDimitry Andric // atomicrmw instructions. We skip this if we want to be doing overflow
24810b57cec5SDimitry Andric // checking, and fall into the slow path with the atomic cmpxchg loop.
24820b57cec5SDimitry Andric if (!type->isBooleanType() && type->isIntegerType() &&
24830b57cec5SDimitry Andric !(type->isUnsignedIntegerType() &&
24840b57cec5SDimitry Andric CGF.SanOpts.has(SanitizerKind::UnsignedIntegerOverflow)) &&
24850b57cec5SDimitry Andric CGF.getLangOpts().getSignedOverflowBehavior() !=
24860b57cec5SDimitry Andric LangOptions::SOB_Trapping) {
24870b57cec5SDimitry Andric llvm::AtomicRMWInst::BinOp aop = isInc ? llvm::AtomicRMWInst::Add :
24880b57cec5SDimitry Andric llvm::AtomicRMWInst::Sub;
24890b57cec5SDimitry Andric llvm::Instruction::BinaryOps op = isInc ? llvm::Instruction::Add :
24900b57cec5SDimitry Andric llvm::Instruction::Sub;
24910b57cec5SDimitry Andric llvm::Value *amt = CGF.EmitToMemory(
24920b57cec5SDimitry Andric llvm::ConstantInt::get(ConvertType(type), 1, true), type);
2493480093f4SDimitry Andric llvm::Value *old =
2494480093f4SDimitry Andric Builder.CreateAtomicRMW(aop, LV.getPointer(CGF), amt,
2495480093f4SDimitry Andric llvm::AtomicOrdering::SequentiallyConsistent);
24960b57cec5SDimitry Andric return isPre ? Builder.CreateBinOp(op, old, amt) : old;
24970b57cec5SDimitry Andric }
24980b57cec5SDimitry Andric value = EmitLoadOfLValue(LV, E->getExprLoc());
24990b57cec5SDimitry Andric input = value;
25000b57cec5SDimitry Andric // For every other atomic operation, we need to emit a load-op-cmpxchg loop
25010b57cec5SDimitry Andric llvm::BasicBlock *startBB = Builder.GetInsertBlock();
25020b57cec5SDimitry Andric llvm::BasicBlock *opBB = CGF.createBasicBlock("atomic_op", CGF.CurFn);
25030b57cec5SDimitry Andric value = CGF.EmitToMemory(value, type);
25040b57cec5SDimitry Andric Builder.CreateBr(opBB);
25050b57cec5SDimitry Andric Builder.SetInsertPoint(opBB);
25060b57cec5SDimitry Andric atomicPHI = Builder.CreatePHI(value->getType(), 2);
25070b57cec5SDimitry Andric atomicPHI->addIncoming(value, startBB);
25080b57cec5SDimitry Andric value = atomicPHI;
25090b57cec5SDimitry Andric } else {
25100b57cec5SDimitry Andric value = EmitLoadOfLValue(LV, E->getExprLoc());
25110b57cec5SDimitry Andric input = value;
25120b57cec5SDimitry Andric }
25130b57cec5SDimitry Andric
25140b57cec5SDimitry Andric // Special case of integer increment that we have to check first: bool++.
25150b57cec5SDimitry Andric // Due to promotion rules, we get:
25160b57cec5SDimitry Andric // bool++ -> bool = bool + 1
25170b57cec5SDimitry Andric // -> bool = (int)bool + 1
25180b57cec5SDimitry Andric // -> bool = ((int)bool + 1 != 0)
25190b57cec5SDimitry Andric // An interesting aspect of this is that increment is always true.
25200b57cec5SDimitry Andric // Decrement does not have this property.
25210b57cec5SDimitry Andric if (isInc && type->isBooleanType()) {
25220b57cec5SDimitry Andric value = Builder.getTrue();
25230b57cec5SDimitry Andric
25240b57cec5SDimitry Andric // Most common case by far: integer increment.
25250b57cec5SDimitry Andric } else if (type->isIntegerType()) {
2526480093f4SDimitry Andric QualType promotedType;
2527480093f4SDimitry Andric bool canPerformLossyDemotionCheck = false;
2528480093f4SDimitry Andric if (type->isPromotableIntegerType()) {
2529480093f4SDimitry Andric promotedType = CGF.getContext().getPromotedIntegerType(type);
2530480093f4SDimitry Andric assert(promotedType != type && "Shouldn't promote to the same type.");
2531480093f4SDimitry Andric canPerformLossyDemotionCheck = true;
2532480093f4SDimitry Andric canPerformLossyDemotionCheck &=
2533480093f4SDimitry Andric CGF.getContext().getCanonicalType(type) !=
2534480093f4SDimitry Andric CGF.getContext().getCanonicalType(promotedType);
2535480093f4SDimitry Andric canPerformLossyDemotionCheck &=
2536480093f4SDimitry Andric PromotionIsPotentiallyEligibleForImplicitIntegerConversionCheck(
2537480093f4SDimitry Andric type, promotedType);
2538480093f4SDimitry Andric assert((!canPerformLossyDemotionCheck ||
2539480093f4SDimitry Andric type->isSignedIntegerOrEnumerationType() ||
2540480093f4SDimitry Andric promotedType->isSignedIntegerOrEnumerationType() ||
2541480093f4SDimitry Andric ConvertType(type)->getScalarSizeInBits() ==
2542480093f4SDimitry Andric ConvertType(promotedType)->getScalarSizeInBits()) &&
2543480093f4SDimitry Andric "The following check expects that if we do promotion to different "
2544480093f4SDimitry Andric "underlying canonical type, at least one of the types (either "
2545480093f4SDimitry Andric "base or promoted) will be signed, or the bitwidths will match.");
2546480093f4SDimitry Andric }
2547480093f4SDimitry Andric if (CGF.SanOpts.hasOneOf(
2548480093f4SDimitry Andric SanitizerKind::ImplicitIntegerArithmeticValueChange) &&
2549480093f4SDimitry Andric canPerformLossyDemotionCheck) {
2550480093f4SDimitry Andric // While `x += 1` (for `x` with width less than int) is modeled as
2551480093f4SDimitry Andric // promotion+arithmetics+demotion, and we can catch lossy demotion with
2552480093f4SDimitry Andric // ease; inc/dec with width less than int can't overflow because of
2553480093f4SDimitry Andric // promotion rules, so we omit promotion+demotion, which means that we can
2554480093f4SDimitry Andric // not catch lossy "demotion". Because we still want to catch these cases
2555480093f4SDimitry Andric // when the sanitizer is enabled, we perform the promotion, then perform
2556480093f4SDimitry Andric // the increment/decrement in the wider type, and finally
2557480093f4SDimitry Andric // perform the demotion. This will catch lossy demotions.
2558480093f4SDimitry Andric
2559480093f4SDimitry Andric value = EmitScalarConversion(value, type, promotedType, E->getExprLoc());
2560480093f4SDimitry Andric Value *amt = llvm::ConstantInt::get(value->getType(), amount, true);
2561480093f4SDimitry Andric value = Builder.CreateAdd(value, amt, isInc ? "inc" : "dec");
2562480093f4SDimitry Andric // Do pass non-default ScalarConversionOpts so that sanitizer check is
2563480093f4SDimitry Andric // emitted.
2564480093f4SDimitry Andric value = EmitScalarConversion(value, promotedType, type, E->getExprLoc(),
2565480093f4SDimitry Andric ScalarConversionOpts(CGF.SanOpts));
2566480093f4SDimitry Andric
25670b57cec5SDimitry Andric // Note that signed integer inc/dec with width less than int can't
2568480093f4SDimitry Andric // overflow because of promotion rules; we're just eliding a few steps
2569480093f4SDimitry Andric // here.
2570480093f4SDimitry Andric } else if (E->canOverflow() && type->isSignedIntegerOrEnumerationType()) {
25710b57cec5SDimitry Andric value = EmitIncDecConsiderOverflowBehavior(E, value, isInc);
25720b57cec5SDimitry Andric } else if (E->canOverflow() && type->isUnsignedIntegerType() &&
25730b57cec5SDimitry Andric CGF.SanOpts.has(SanitizerKind::UnsignedIntegerOverflow)) {
25745ffd83dbSDimitry Andric value = EmitOverflowCheckedBinOp(createBinOpInfoFromIncDec(
25755ffd83dbSDimitry Andric E, value, isInc, E->getFPFeaturesInEffect(CGF.getLangOpts())));
25760b57cec5SDimitry Andric } else {
25770b57cec5SDimitry Andric llvm::Value *amt = llvm::ConstantInt::get(value->getType(), amount, true);
25780b57cec5SDimitry Andric value = Builder.CreateAdd(value, amt, isInc ? "inc" : "dec");
25790b57cec5SDimitry Andric }
25800b57cec5SDimitry Andric
25810b57cec5SDimitry Andric // Next most common: pointer increment.
25820b57cec5SDimitry Andric } else if (const PointerType *ptr = type->getAs<PointerType>()) {
25830b57cec5SDimitry Andric QualType type = ptr->getPointeeType();
25840b57cec5SDimitry Andric
25850b57cec5SDimitry Andric // VLA types don't have constant size.
25860b57cec5SDimitry Andric if (const VariableArrayType *vla
25870b57cec5SDimitry Andric = CGF.getContext().getAsVariableArrayType(type)) {
25880b57cec5SDimitry Andric llvm::Value *numElts = CGF.getVLASize(vla).NumElts;
25890b57cec5SDimitry Andric if (!isInc) numElts = Builder.CreateNSWNeg(numElts, "vla.negsize");
25900b57cec5SDimitry Andric if (CGF.getLangOpts().isSignedOverflowDefined())
2591*5f7ddb14SDimitry Andric value = Builder.CreateGEP(value->getType()->getPointerElementType(),
2592*5f7ddb14SDimitry Andric value, numElts, "vla.inc");
25930b57cec5SDimitry Andric else
25940b57cec5SDimitry Andric value = CGF.EmitCheckedInBoundsGEP(
25950b57cec5SDimitry Andric value, numElts, /*SignedIndices=*/false, isSubtraction,
25960b57cec5SDimitry Andric E->getExprLoc(), "vla.inc");
25970b57cec5SDimitry Andric
25980b57cec5SDimitry Andric // Arithmetic on function pointers (!) is just +-1.
25990b57cec5SDimitry Andric } else if (type->isFunctionType()) {
26000b57cec5SDimitry Andric llvm::Value *amt = Builder.getInt32(amount);
26010b57cec5SDimitry Andric
26020b57cec5SDimitry Andric value = CGF.EmitCastToVoidPtr(value);
26030b57cec5SDimitry Andric if (CGF.getLangOpts().isSignedOverflowDefined())
2604*5f7ddb14SDimitry Andric value = Builder.CreateGEP(CGF.Int8Ty, value, amt, "incdec.funcptr");
26050b57cec5SDimitry Andric else
26060b57cec5SDimitry Andric value = CGF.EmitCheckedInBoundsGEP(value, amt, /*SignedIndices=*/false,
26070b57cec5SDimitry Andric isSubtraction, E->getExprLoc(),
26080b57cec5SDimitry Andric "incdec.funcptr");
26090b57cec5SDimitry Andric value = Builder.CreateBitCast(value, input->getType());
26100b57cec5SDimitry Andric
26110b57cec5SDimitry Andric // For everything else, we can just do a simple increment.
26120b57cec5SDimitry Andric } else {
26130b57cec5SDimitry Andric llvm::Value *amt = Builder.getInt32(amount);
26140b57cec5SDimitry Andric if (CGF.getLangOpts().isSignedOverflowDefined())
2615*5f7ddb14SDimitry Andric value = Builder.CreateGEP(value->getType()->getPointerElementType(),
2616*5f7ddb14SDimitry Andric value, amt, "incdec.ptr");
26170b57cec5SDimitry Andric else
26180b57cec5SDimitry Andric value = CGF.EmitCheckedInBoundsGEP(value, amt, /*SignedIndices=*/false,
26190b57cec5SDimitry Andric isSubtraction, E->getExprLoc(),
26200b57cec5SDimitry Andric "incdec.ptr");
26210b57cec5SDimitry Andric }
26220b57cec5SDimitry Andric
26230b57cec5SDimitry Andric // Vector increment/decrement.
26240b57cec5SDimitry Andric } else if (type->isVectorType()) {
26250b57cec5SDimitry Andric if (type->hasIntegerRepresentation()) {
26260b57cec5SDimitry Andric llvm::Value *amt = llvm::ConstantInt::get(value->getType(), amount);
26270b57cec5SDimitry Andric
26280b57cec5SDimitry Andric value = Builder.CreateAdd(value, amt, isInc ? "inc" : "dec");
26290b57cec5SDimitry Andric } else {
26300b57cec5SDimitry Andric value = Builder.CreateFAdd(
26310b57cec5SDimitry Andric value,
26320b57cec5SDimitry Andric llvm::ConstantFP::get(value->getType(), amount),
26330b57cec5SDimitry Andric isInc ? "inc" : "dec");
26340b57cec5SDimitry Andric }
26350b57cec5SDimitry Andric
26360b57cec5SDimitry Andric // Floating point.
26370b57cec5SDimitry Andric } else if (type->isRealFloatingType()) {
26380b57cec5SDimitry Andric // Add the inc/dec to the real part.
26390b57cec5SDimitry Andric llvm::Value *amt;
2640af732203SDimitry Andric CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, E);
26410b57cec5SDimitry Andric
26420b57cec5SDimitry Andric if (type->isHalfType() && !CGF.getContext().getLangOpts().NativeHalfType) {
26430b57cec5SDimitry Andric // Another special case: half FP increment should be done via float
26440b57cec5SDimitry Andric if (CGF.getContext().getTargetInfo().useFP16ConversionIntrinsics()) {
26450b57cec5SDimitry Andric value = Builder.CreateCall(
26460b57cec5SDimitry Andric CGF.CGM.getIntrinsic(llvm::Intrinsic::convert_from_fp16,
26470b57cec5SDimitry Andric CGF.CGM.FloatTy),
26480b57cec5SDimitry Andric input, "incdec.conv");
26490b57cec5SDimitry Andric } else {
26500b57cec5SDimitry Andric value = Builder.CreateFPExt(input, CGF.CGM.FloatTy, "incdec.conv");
26510b57cec5SDimitry Andric }
26520b57cec5SDimitry Andric }
26530b57cec5SDimitry Andric
26540b57cec5SDimitry Andric if (value->getType()->isFloatTy())
26550b57cec5SDimitry Andric amt = llvm::ConstantFP::get(VMContext,
26560b57cec5SDimitry Andric llvm::APFloat(static_cast<float>(amount)));
26570b57cec5SDimitry Andric else if (value->getType()->isDoubleTy())
26580b57cec5SDimitry Andric amt = llvm::ConstantFP::get(VMContext,
26590b57cec5SDimitry Andric llvm::APFloat(static_cast<double>(amount)));
26600b57cec5SDimitry Andric else {
26610b57cec5SDimitry Andric // Remaining types are Half, LongDouble or __float128. Convert from float.
26620b57cec5SDimitry Andric llvm::APFloat F(static_cast<float>(amount));
26630b57cec5SDimitry Andric bool ignored;
26640b57cec5SDimitry Andric const llvm::fltSemantics *FS;
26650b57cec5SDimitry Andric // Don't use getFloatTypeSemantics because Half isn't
26660b57cec5SDimitry Andric // necessarily represented using the "half" LLVM type.
26670b57cec5SDimitry Andric if (value->getType()->isFP128Ty())
26680b57cec5SDimitry Andric FS = &CGF.getTarget().getFloat128Format();
26690b57cec5SDimitry Andric else if (value->getType()->isHalfTy())
26700b57cec5SDimitry Andric FS = &CGF.getTarget().getHalfFormat();
26710b57cec5SDimitry Andric else
26720b57cec5SDimitry Andric FS = &CGF.getTarget().getLongDoubleFormat();
26730b57cec5SDimitry Andric F.convert(*FS, llvm::APFloat::rmTowardZero, &ignored);
26740b57cec5SDimitry Andric amt = llvm::ConstantFP::get(VMContext, F);
26750b57cec5SDimitry Andric }
26760b57cec5SDimitry Andric value = Builder.CreateFAdd(value, amt, isInc ? "inc" : "dec");
26770b57cec5SDimitry Andric
26780b57cec5SDimitry Andric if (type->isHalfType() && !CGF.getContext().getLangOpts().NativeHalfType) {
26790b57cec5SDimitry Andric if (CGF.getContext().getTargetInfo().useFP16ConversionIntrinsics()) {
26800b57cec5SDimitry Andric value = Builder.CreateCall(
26810b57cec5SDimitry Andric CGF.CGM.getIntrinsic(llvm::Intrinsic::convert_to_fp16,
26820b57cec5SDimitry Andric CGF.CGM.FloatTy),
26830b57cec5SDimitry Andric value, "incdec.conv");
26840b57cec5SDimitry Andric } else {
26850b57cec5SDimitry Andric value = Builder.CreateFPTrunc(value, input->getType(), "incdec.conv");
26860b57cec5SDimitry Andric }
26870b57cec5SDimitry Andric }
26880b57cec5SDimitry Andric
26895ffd83dbSDimitry Andric // Fixed-point types.
26905ffd83dbSDimitry Andric } else if (type->isFixedPointType()) {
26915ffd83dbSDimitry Andric // Fixed-point types are tricky. In some cases, it isn't possible to
26925ffd83dbSDimitry Andric // represent a 1 or a -1 in the type at all. Piggyback off of
26935ffd83dbSDimitry Andric // EmitFixedPointBinOp to avoid having to reimplement saturation.
26945ffd83dbSDimitry Andric BinOpInfo Info;
26955ffd83dbSDimitry Andric Info.E = E;
26965ffd83dbSDimitry Andric Info.Ty = E->getType();
26975ffd83dbSDimitry Andric Info.Opcode = isInc ? BO_Add : BO_Sub;
26985ffd83dbSDimitry Andric Info.LHS = value;
26995ffd83dbSDimitry Andric Info.RHS = llvm::ConstantInt::get(value->getType(), 1, false);
27005ffd83dbSDimitry Andric // If the type is signed, it's better to represent this as +(-1) or -(-1),
27015ffd83dbSDimitry Andric // since -1 is guaranteed to be representable.
27025ffd83dbSDimitry Andric if (type->isSignedFixedPointType()) {
27035ffd83dbSDimitry Andric Info.Opcode = isInc ? BO_Sub : BO_Add;
27045ffd83dbSDimitry Andric Info.RHS = Builder.CreateNeg(Info.RHS);
27055ffd83dbSDimitry Andric }
27065ffd83dbSDimitry Andric // Now, convert from our invented integer literal to the type of the unary
27075ffd83dbSDimitry Andric // op. This will upscale and saturate if necessary. This value can become
27085ffd83dbSDimitry Andric // undef in some cases.
2709af732203SDimitry Andric llvm::FixedPointBuilder<CGBuilderTy> FPBuilder(Builder);
2710af732203SDimitry Andric auto DstSema = CGF.getContext().getFixedPointSemantics(Info.Ty);
2711af732203SDimitry Andric Info.RHS = FPBuilder.CreateIntegerToFixed(Info.RHS, true, DstSema);
27125ffd83dbSDimitry Andric value = EmitFixedPointBinOp(Info);
27135ffd83dbSDimitry Andric
27140b57cec5SDimitry Andric // Objective-C pointer types.
27150b57cec5SDimitry Andric } else {
27160b57cec5SDimitry Andric const ObjCObjectPointerType *OPT = type->castAs<ObjCObjectPointerType>();
27170b57cec5SDimitry Andric value = CGF.EmitCastToVoidPtr(value);
27180b57cec5SDimitry Andric
27190b57cec5SDimitry Andric CharUnits size = CGF.getContext().getTypeSizeInChars(OPT->getObjectType());
27200b57cec5SDimitry Andric if (!isInc) size = -size;
27210b57cec5SDimitry Andric llvm::Value *sizeValue =
27220b57cec5SDimitry Andric llvm::ConstantInt::get(CGF.SizeTy, size.getQuantity());
27230b57cec5SDimitry Andric
27240b57cec5SDimitry Andric if (CGF.getLangOpts().isSignedOverflowDefined())
2725*5f7ddb14SDimitry Andric value = Builder.CreateGEP(CGF.Int8Ty, value, sizeValue, "incdec.objptr");
27260b57cec5SDimitry Andric else
27270b57cec5SDimitry Andric value = CGF.EmitCheckedInBoundsGEP(value, sizeValue,
27280b57cec5SDimitry Andric /*SignedIndices=*/false, isSubtraction,
27290b57cec5SDimitry Andric E->getExprLoc(), "incdec.objptr");
27300b57cec5SDimitry Andric value = Builder.CreateBitCast(value, input->getType());
27310b57cec5SDimitry Andric }
27320b57cec5SDimitry Andric
27330b57cec5SDimitry Andric if (atomicPHI) {
27340b57cec5SDimitry Andric llvm::BasicBlock *curBlock = Builder.GetInsertBlock();
27350b57cec5SDimitry Andric llvm::BasicBlock *contBB = CGF.createBasicBlock("atomic_cont", CGF.CurFn);
27360b57cec5SDimitry Andric auto Pair = CGF.EmitAtomicCompareExchange(
27370b57cec5SDimitry Andric LV, RValue::get(atomicPHI), RValue::get(value), E->getExprLoc());
27380b57cec5SDimitry Andric llvm::Value *old = CGF.EmitToMemory(Pair.first.getScalarVal(), type);
27390b57cec5SDimitry Andric llvm::Value *success = Pair.second;
27400b57cec5SDimitry Andric atomicPHI->addIncoming(old, curBlock);
27410b57cec5SDimitry Andric Builder.CreateCondBr(success, contBB, atomicPHI->getParent());
27420b57cec5SDimitry Andric Builder.SetInsertPoint(contBB);
27430b57cec5SDimitry Andric return isPre ? value : input;
27440b57cec5SDimitry Andric }
27450b57cec5SDimitry Andric
27460b57cec5SDimitry Andric // Store the updated result through the lvalue.
27470b57cec5SDimitry Andric if (LV.isBitField())
27480b57cec5SDimitry Andric CGF.EmitStoreThroughBitfieldLValue(RValue::get(value), LV, &value);
27490b57cec5SDimitry Andric else
27500b57cec5SDimitry Andric CGF.EmitStoreThroughLValue(RValue::get(value), LV);
27510b57cec5SDimitry Andric
27520b57cec5SDimitry Andric // If this is a postinc, return the value read from memory, otherwise use the
27530b57cec5SDimitry Andric // updated value.
27540b57cec5SDimitry Andric return isPre ? value : input;
27550b57cec5SDimitry Andric }
27560b57cec5SDimitry Andric
27570b57cec5SDimitry Andric
27580b57cec5SDimitry Andric
VisitUnaryMinus(const UnaryOperator * E)27590b57cec5SDimitry Andric Value *ScalarExprEmitter::VisitUnaryMinus(const UnaryOperator *E) {
27600b57cec5SDimitry Andric TestAndClearIgnoreResultAssign();
2761a7dea167SDimitry Andric Value *Op = Visit(E->getSubExpr());
2762a7dea167SDimitry Andric
2763a7dea167SDimitry Andric // Generate a unary FNeg for FP ops.
2764a7dea167SDimitry Andric if (Op->getType()->isFPOrFPVectorTy())
2765a7dea167SDimitry Andric return Builder.CreateFNeg(Op, "fneg");
2766a7dea167SDimitry Andric
27670b57cec5SDimitry Andric // Emit unary minus with EmitSub so we handle overflow cases etc.
27680b57cec5SDimitry Andric BinOpInfo BinOp;
2769a7dea167SDimitry Andric BinOp.RHS = Op;
27700b57cec5SDimitry Andric BinOp.LHS = llvm::Constant::getNullValue(BinOp.RHS->getType());
27710b57cec5SDimitry Andric BinOp.Ty = E->getType();
27720b57cec5SDimitry Andric BinOp.Opcode = BO_Sub;
27735ffd83dbSDimitry Andric BinOp.FPFeatures = E->getFPFeaturesInEffect(CGF.getLangOpts());
27740b57cec5SDimitry Andric BinOp.E = E;
27750b57cec5SDimitry Andric return EmitSub(BinOp);
27760b57cec5SDimitry Andric }
27770b57cec5SDimitry Andric
VisitUnaryNot(const UnaryOperator * E)27780b57cec5SDimitry Andric Value *ScalarExprEmitter::VisitUnaryNot(const UnaryOperator *E) {
27790b57cec5SDimitry Andric TestAndClearIgnoreResultAssign();
27800b57cec5SDimitry Andric Value *Op = Visit(E->getSubExpr());
27810b57cec5SDimitry Andric return Builder.CreateNot(Op, "neg");
27820b57cec5SDimitry Andric }
27830b57cec5SDimitry Andric
VisitUnaryLNot(const UnaryOperator * E)27840b57cec5SDimitry Andric Value *ScalarExprEmitter::VisitUnaryLNot(const UnaryOperator *E) {
27850b57cec5SDimitry Andric // Perform vector logical not on comparison with zero vector.
27865ffd83dbSDimitry Andric if (E->getType()->isVectorType() &&
27875ffd83dbSDimitry Andric E->getType()->castAs<VectorType>()->getVectorKind() ==
27885ffd83dbSDimitry Andric VectorType::GenericVector) {
27890b57cec5SDimitry Andric Value *Oper = Visit(E->getSubExpr());
27900b57cec5SDimitry Andric Value *Zero = llvm::Constant::getNullValue(Oper->getType());
27910b57cec5SDimitry Andric Value *Result;
27925ffd83dbSDimitry Andric if (Oper->getType()->isFPOrFPVectorTy()) {
27935ffd83dbSDimitry Andric CodeGenFunction::CGFPOptionsRAII FPOptsRAII(
27945ffd83dbSDimitry Andric CGF, E->getFPFeaturesInEffect(CGF.getLangOpts()));
27950b57cec5SDimitry Andric Result = Builder.CreateFCmp(llvm::CmpInst::FCMP_OEQ, Oper, Zero, "cmp");
27965ffd83dbSDimitry Andric } else
27970b57cec5SDimitry Andric Result = Builder.CreateICmp(llvm::CmpInst::ICMP_EQ, Oper, Zero, "cmp");
27980b57cec5SDimitry Andric return Builder.CreateSExt(Result, ConvertType(E->getType()), "sext");
27990b57cec5SDimitry Andric }
28000b57cec5SDimitry Andric
28010b57cec5SDimitry Andric // Compare operand to zero.
28020b57cec5SDimitry Andric Value *BoolVal = CGF.EvaluateExprAsBool(E->getSubExpr());
28030b57cec5SDimitry Andric
28040b57cec5SDimitry Andric // Invert value.
28050b57cec5SDimitry Andric // TODO: Could dynamically modify easy computations here. For example, if
28060b57cec5SDimitry Andric // the operand is an icmp ne, turn into icmp eq.
28070b57cec5SDimitry Andric BoolVal = Builder.CreateNot(BoolVal, "lnot");
28080b57cec5SDimitry Andric
28090b57cec5SDimitry Andric // ZExt result to the expr type.
28100b57cec5SDimitry Andric return Builder.CreateZExt(BoolVal, ConvertType(E->getType()), "lnot.ext");
28110b57cec5SDimitry Andric }
28120b57cec5SDimitry Andric
VisitOffsetOfExpr(OffsetOfExpr * E)28130b57cec5SDimitry Andric Value *ScalarExprEmitter::VisitOffsetOfExpr(OffsetOfExpr *E) {
28140b57cec5SDimitry Andric // Try folding the offsetof to a constant.
28150b57cec5SDimitry Andric Expr::EvalResult EVResult;
28160b57cec5SDimitry Andric if (E->EvaluateAsInt(EVResult, CGF.getContext())) {
28170b57cec5SDimitry Andric llvm::APSInt Value = EVResult.Val.getInt();
28180b57cec5SDimitry Andric return Builder.getInt(Value);
28190b57cec5SDimitry Andric }
28200b57cec5SDimitry Andric
28210b57cec5SDimitry Andric // Loop over the components of the offsetof to compute the value.
28220b57cec5SDimitry Andric unsigned n = E->getNumComponents();
28230b57cec5SDimitry Andric llvm::Type* ResultType = ConvertType(E->getType());
28240b57cec5SDimitry Andric llvm::Value* Result = llvm::Constant::getNullValue(ResultType);
28250b57cec5SDimitry Andric QualType CurrentType = E->getTypeSourceInfo()->getType();
28260b57cec5SDimitry Andric for (unsigned i = 0; i != n; ++i) {
28270b57cec5SDimitry Andric OffsetOfNode ON = E->getComponent(i);
28280b57cec5SDimitry Andric llvm::Value *Offset = nullptr;
28290b57cec5SDimitry Andric switch (ON.getKind()) {
28300b57cec5SDimitry Andric case OffsetOfNode::Array: {
28310b57cec5SDimitry Andric // Compute the index
28320b57cec5SDimitry Andric Expr *IdxExpr = E->getIndexExpr(ON.getArrayExprIndex());
28330b57cec5SDimitry Andric llvm::Value* Idx = CGF.EmitScalarExpr(IdxExpr);
28340b57cec5SDimitry Andric bool IdxSigned = IdxExpr->getType()->isSignedIntegerOrEnumerationType();
28350b57cec5SDimitry Andric Idx = Builder.CreateIntCast(Idx, ResultType, IdxSigned, "conv");
28360b57cec5SDimitry Andric
28370b57cec5SDimitry Andric // Save the element type
28380b57cec5SDimitry Andric CurrentType =
28390b57cec5SDimitry Andric CGF.getContext().getAsArrayType(CurrentType)->getElementType();
28400b57cec5SDimitry Andric
28410b57cec5SDimitry Andric // Compute the element size
28420b57cec5SDimitry Andric llvm::Value* ElemSize = llvm::ConstantInt::get(ResultType,
28430b57cec5SDimitry Andric CGF.getContext().getTypeSizeInChars(CurrentType).getQuantity());
28440b57cec5SDimitry Andric
28450b57cec5SDimitry Andric // Multiply out to compute the result
28460b57cec5SDimitry Andric Offset = Builder.CreateMul(Idx, ElemSize);
28470b57cec5SDimitry Andric break;
28480b57cec5SDimitry Andric }
28490b57cec5SDimitry Andric
28500b57cec5SDimitry Andric case OffsetOfNode::Field: {
28510b57cec5SDimitry Andric FieldDecl *MemberDecl = ON.getField();
2852a7dea167SDimitry Andric RecordDecl *RD = CurrentType->castAs<RecordType>()->getDecl();
28530b57cec5SDimitry Andric const ASTRecordLayout &RL = CGF.getContext().getASTRecordLayout(RD);
28540b57cec5SDimitry Andric
28550b57cec5SDimitry Andric // Compute the index of the field in its parent.
28560b57cec5SDimitry Andric unsigned i = 0;
28570b57cec5SDimitry Andric // FIXME: It would be nice if we didn't have to loop here!
28580b57cec5SDimitry Andric for (RecordDecl::field_iterator Field = RD->field_begin(),
28590b57cec5SDimitry Andric FieldEnd = RD->field_end();
28600b57cec5SDimitry Andric Field != FieldEnd; ++Field, ++i) {
28610b57cec5SDimitry Andric if (*Field == MemberDecl)
28620b57cec5SDimitry Andric break;
28630b57cec5SDimitry Andric }
28640b57cec5SDimitry Andric assert(i < RL.getFieldCount() && "offsetof field in wrong type");
28650b57cec5SDimitry Andric
28660b57cec5SDimitry Andric // Compute the offset to the field
28670b57cec5SDimitry Andric int64_t OffsetInt = RL.getFieldOffset(i) /
28680b57cec5SDimitry Andric CGF.getContext().getCharWidth();
28690b57cec5SDimitry Andric Offset = llvm::ConstantInt::get(ResultType, OffsetInt);
28700b57cec5SDimitry Andric
28710b57cec5SDimitry Andric // Save the element type.
28720b57cec5SDimitry Andric CurrentType = MemberDecl->getType();
28730b57cec5SDimitry Andric break;
28740b57cec5SDimitry Andric }
28750b57cec5SDimitry Andric
28760b57cec5SDimitry Andric case OffsetOfNode::Identifier:
28770b57cec5SDimitry Andric llvm_unreachable("dependent __builtin_offsetof");
28780b57cec5SDimitry Andric
28790b57cec5SDimitry Andric case OffsetOfNode::Base: {
28800b57cec5SDimitry Andric if (ON.getBase()->isVirtual()) {
28810b57cec5SDimitry Andric CGF.ErrorUnsupported(E, "virtual base in offsetof");
28820b57cec5SDimitry Andric continue;
28830b57cec5SDimitry Andric }
28840b57cec5SDimitry Andric
2885a7dea167SDimitry Andric RecordDecl *RD = CurrentType->castAs<RecordType>()->getDecl();
28860b57cec5SDimitry Andric const ASTRecordLayout &RL = CGF.getContext().getASTRecordLayout(RD);
28870b57cec5SDimitry Andric
28880b57cec5SDimitry Andric // Save the element type.
28890b57cec5SDimitry Andric CurrentType = ON.getBase()->getType();
28900b57cec5SDimitry Andric
28910b57cec5SDimitry Andric // Compute the offset to the base.
28920b57cec5SDimitry Andric const RecordType *BaseRT = CurrentType->getAs<RecordType>();
28930b57cec5SDimitry Andric CXXRecordDecl *BaseRD = cast<CXXRecordDecl>(BaseRT->getDecl());
28940b57cec5SDimitry Andric CharUnits OffsetInt = RL.getBaseClassOffset(BaseRD);
28950b57cec5SDimitry Andric Offset = llvm::ConstantInt::get(ResultType, OffsetInt.getQuantity());
28960b57cec5SDimitry Andric break;
28970b57cec5SDimitry Andric }
28980b57cec5SDimitry Andric }
28990b57cec5SDimitry Andric Result = Builder.CreateAdd(Result, Offset);
29000b57cec5SDimitry Andric }
29010b57cec5SDimitry Andric return Result;
29020b57cec5SDimitry Andric }
29030b57cec5SDimitry Andric
29040b57cec5SDimitry Andric /// VisitUnaryExprOrTypeTraitExpr - Return the size or alignment of the type of
29050b57cec5SDimitry Andric /// argument of the sizeof expression as an integer.
29060b57cec5SDimitry Andric Value *
VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr * E)29070b57cec5SDimitry Andric ScalarExprEmitter::VisitUnaryExprOrTypeTraitExpr(
29080b57cec5SDimitry Andric const UnaryExprOrTypeTraitExpr *E) {
29090b57cec5SDimitry Andric QualType TypeToSize = E->getTypeOfArgument();
29100b57cec5SDimitry Andric if (E->getKind() == UETT_SizeOf) {
29110b57cec5SDimitry Andric if (const VariableArrayType *VAT =
29120b57cec5SDimitry Andric CGF.getContext().getAsVariableArrayType(TypeToSize)) {
29130b57cec5SDimitry Andric if (E->isArgumentType()) {
29140b57cec5SDimitry Andric // sizeof(type) - make sure to emit the VLA size.
29150b57cec5SDimitry Andric CGF.EmitVariablyModifiedType(TypeToSize);
29160b57cec5SDimitry Andric } else {
29170b57cec5SDimitry Andric // C99 6.5.3.4p2: If the argument is an expression of type
29180b57cec5SDimitry Andric // VLA, it is evaluated.
29190b57cec5SDimitry Andric CGF.EmitIgnoredExpr(E->getArgumentExpr());
29200b57cec5SDimitry Andric }
29210b57cec5SDimitry Andric
29220b57cec5SDimitry Andric auto VlaSize = CGF.getVLASize(VAT);
29230b57cec5SDimitry Andric llvm::Value *size = VlaSize.NumElts;
29240b57cec5SDimitry Andric
29250b57cec5SDimitry Andric // Scale the number of non-VLA elements by the non-VLA element size.
29260b57cec5SDimitry Andric CharUnits eltSize = CGF.getContext().getTypeSizeInChars(VlaSize.Type);
29270b57cec5SDimitry Andric if (!eltSize.isOne())
29280b57cec5SDimitry Andric size = CGF.Builder.CreateNUWMul(CGF.CGM.getSize(eltSize), size);
29290b57cec5SDimitry Andric
29300b57cec5SDimitry Andric return size;
29310b57cec5SDimitry Andric }
29320b57cec5SDimitry Andric } else if (E->getKind() == UETT_OpenMPRequiredSimdAlign) {
29330b57cec5SDimitry Andric auto Alignment =
29340b57cec5SDimitry Andric CGF.getContext()
29350b57cec5SDimitry Andric .toCharUnitsFromBits(CGF.getContext().getOpenMPDefaultSimdAlign(
29360b57cec5SDimitry Andric E->getTypeOfArgument()->getPointeeType()))
29370b57cec5SDimitry Andric .getQuantity();
29380b57cec5SDimitry Andric return llvm::ConstantInt::get(CGF.SizeTy, Alignment);
29390b57cec5SDimitry Andric }
29400b57cec5SDimitry Andric
29410b57cec5SDimitry Andric // If this isn't sizeof(vla), the result must be constant; use the constant
29420b57cec5SDimitry Andric // folding logic so we don't have to duplicate it here.
29430b57cec5SDimitry Andric return Builder.getInt(E->EvaluateKnownConstInt(CGF.getContext()));
29440b57cec5SDimitry Andric }
29450b57cec5SDimitry Andric
VisitUnaryReal(const UnaryOperator * E)29460b57cec5SDimitry Andric Value *ScalarExprEmitter::VisitUnaryReal(const UnaryOperator *E) {
29470b57cec5SDimitry Andric Expr *Op = E->getSubExpr();
29480b57cec5SDimitry Andric if (Op->getType()->isAnyComplexType()) {
29490b57cec5SDimitry Andric // If it's an l-value, load through the appropriate subobject l-value.
29500b57cec5SDimitry Andric // Note that we have to ask E because Op might be an l-value that
29510b57cec5SDimitry Andric // this won't work for, e.g. an Obj-C property.
29520b57cec5SDimitry Andric if (E->isGLValue())
29530b57cec5SDimitry Andric return CGF.EmitLoadOfLValue(CGF.EmitLValue(E),
29540b57cec5SDimitry Andric E->getExprLoc()).getScalarVal();
29550b57cec5SDimitry Andric
29560b57cec5SDimitry Andric // Otherwise, calculate and project.
29570b57cec5SDimitry Andric return CGF.EmitComplexExpr(Op, false, true).first;
29580b57cec5SDimitry Andric }
29590b57cec5SDimitry Andric
29600b57cec5SDimitry Andric return Visit(Op);
29610b57cec5SDimitry Andric }
29620b57cec5SDimitry Andric
VisitUnaryImag(const UnaryOperator * E)29630b57cec5SDimitry Andric Value *ScalarExprEmitter::VisitUnaryImag(const UnaryOperator *E) {
29640b57cec5SDimitry Andric Expr *Op = E->getSubExpr();
29650b57cec5SDimitry Andric if (Op->getType()->isAnyComplexType()) {
29660b57cec5SDimitry Andric // If it's an l-value, load through the appropriate subobject l-value.
29670b57cec5SDimitry Andric // Note that we have to ask E because Op might be an l-value that
29680b57cec5SDimitry Andric // this won't work for, e.g. an Obj-C property.
29690b57cec5SDimitry Andric if (Op->isGLValue())
29700b57cec5SDimitry Andric return CGF.EmitLoadOfLValue(CGF.EmitLValue(E),
29710b57cec5SDimitry Andric E->getExprLoc()).getScalarVal();
29720b57cec5SDimitry Andric
29730b57cec5SDimitry Andric // Otherwise, calculate and project.
29740b57cec5SDimitry Andric return CGF.EmitComplexExpr(Op, true, false).second;
29750b57cec5SDimitry Andric }
29760b57cec5SDimitry Andric
29770b57cec5SDimitry Andric // __imag on a scalar returns zero. Emit the subexpr to ensure side
29780b57cec5SDimitry Andric // effects are evaluated, but not the actual value.
29790b57cec5SDimitry Andric if (Op->isGLValue())
29800b57cec5SDimitry Andric CGF.EmitLValue(Op);
29810b57cec5SDimitry Andric else
29820b57cec5SDimitry Andric CGF.EmitScalarExpr(Op, true);
29830b57cec5SDimitry Andric return llvm::Constant::getNullValue(ConvertType(E->getType()));
29840b57cec5SDimitry Andric }
29850b57cec5SDimitry Andric
29860b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
29870b57cec5SDimitry Andric // Binary Operators
29880b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
29890b57cec5SDimitry Andric
EmitBinOps(const BinaryOperator * E)29900b57cec5SDimitry Andric BinOpInfo ScalarExprEmitter::EmitBinOps(const BinaryOperator *E) {
29910b57cec5SDimitry Andric TestAndClearIgnoreResultAssign();
29920b57cec5SDimitry Andric BinOpInfo Result;
29930b57cec5SDimitry Andric Result.LHS = Visit(E->getLHS());
29940b57cec5SDimitry Andric Result.RHS = Visit(E->getRHS());
29950b57cec5SDimitry Andric Result.Ty = E->getType();
29960b57cec5SDimitry Andric Result.Opcode = E->getOpcode();
29975ffd83dbSDimitry Andric Result.FPFeatures = E->getFPFeaturesInEffect(CGF.getLangOpts());
29980b57cec5SDimitry Andric Result.E = E;
29990b57cec5SDimitry Andric return Result;
30000b57cec5SDimitry Andric }
30010b57cec5SDimitry Andric
EmitCompoundAssignLValue(const CompoundAssignOperator * E,Value * (ScalarExprEmitter::* Func)(const BinOpInfo &),Value * & Result)30020b57cec5SDimitry Andric LValue ScalarExprEmitter::EmitCompoundAssignLValue(
30030b57cec5SDimitry Andric const CompoundAssignOperator *E,
30040b57cec5SDimitry Andric Value *(ScalarExprEmitter::*Func)(const BinOpInfo &),
30050b57cec5SDimitry Andric Value *&Result) {
30060b57cec5SDimitry Andric QualType LHSTy = E->getLHS()->getType();
30070b57cec5SDimitry Andric BinOpInfo OpInfo;
30080b57cec5SDimitry Andric
30090b57cec5SDimitry Andric if (E->getComputationResultType()->isAnyComplexType())
30100b57cec5SDimitry Andric return CGF.EmitScalarCompoundAssignWithComplex(E, Result);
30110b57cec5SDimitry Andric
30120b57cec5SDimitry Andric // Emit the RHS first. __block variables need to have the rhs evaluated
30130b57cec5SDimitry Andric // first, plus this should improve codegen a little.
30140b57cec5SDimitry Andric OpInfo.RHS = Visit(E->getRHS());
30150b57cec5SDimitry Andric OpInfo.Ty = E->getComputationResultType();
30160b57cec5SDimitry Andric OpInfo.Opcode = E->getOpcode();
30175ffd83dbSDimitry Andric OpInfo.FPFeatures = E->getFPFeaturesInEffect(CGF.getLangOpts());
30180b57cec5SDimitry Andric OpInfo.E = E;
30190b57cec5SDimitry Andric // Load/convert the LHS.
30200b57cec5SDimitry Andric LValue LHSLV = EmitCheckedLValue(E->getLHS(), CodeGenFunction::TCK_Store);
30210b57cec5SDimitry Andric
30220b57cec5SDimitry Andric llvm::PHINode *atomicPHI = nullptr;
30230b57cec5SDimitry Andric if (const AtomicType *atomicTy = LHSTy->getAs<AtomicType>()) {
30240b57cec5SDimitry Andric QualType type = atomicTy->getValueType();
30250b57cec5SDimitry Andric if (!type->isBooleanType() && type->isIntegerType() &&
30260b57cec5SDimitry Andric !(type->isUnsignedIntegerType() &&
30270b57cec5SDimitry Andric CGF.SanOpts.has(SanitizerKind::UnsignedIntegerOverflow)) &&
30280b57cec5SDimitry Andric CGF.getLangOpts().getSignedOverflowBehavior() !=
30290b57cec5SDimitry Andric LangOptions::SOB_Trapping) {
3030480093f4SDimitry Andric llvm::AtomicRMWInst::BinOp AtomicOp = llvm::AtomicRMWInst::BAD_BINOP;
3031480093f4SDimitry Andric llvm::Instruction::BinaryOps Op;
30320b57cec5SDimitry Andric switch (OpInfo.Opcode) {
30330b57cec5SDimitry Andric // We don't have atomicrmw operands for *, %, /, <<, >>
30340b57cec5SDimitry Andric case BO_MulAssign: case BO_DivAssign:
30350b57cec5SDimitry Andric case BO_RemAssign:
30360b57cec5SDimitry Andric case BO_ShlAssign:
30370b57cec5SDimitry Andric case BO_ShrAssign:
30380b57cec5SDimitry Andric break;
30390b57cec5SDimitry Andric case BO_AddAssign:
3040480093f4SDimitry Andric AtomicOp = llvm::AtomicRMWInst::Add;
3041480093f4SDimitry Andric Op = llvm::Instruction::Add;
30420b57cec5SDimitry Andric break;
30430b57cec5SDimitry Andric case BO_SubAssign:
3044480093f4SDimitry Andric AtomicOp = llvm::AtomicRMWInst::Sub;
3045480093f4SDimitry Andric Op = llvm::Instruction::Sub;
30460b57cec5SDimitry Andric break;
30470b57cec5SDimitry Andric case BO_AndAssign:
3048480093f4SDimitry Andric AtomicOp = llvm::AtomicRMWInst::And;
3049480093f4SDimitry Andric Op = llvm::Instruction::And;
30500b57cec5SDimitry Andric break;
30510b57cec5SDimitry Andric case BO_XorAssign:
3052480093f4SDimitry Andric AtomicOp = llvm::AtomicRMWInst::Xor;
3053480093f4SDimitry Andric Op = llvm::Instruction::Xor;
30540b57cec5SDimitry Andric break;
30550b57cec5SDimitry Andric case BO_OrAssign:
3056480093f4SDimitry Andric AtomicOp = llvm::AtomicRMWInst::Or;
3057480093f4SDimitry Andric Op = llvm::Instruction::Or;
30580b57cec5SDimitry Andric break;
30590b57cec5SDimitry Andric default:
30600b57cec5SDimitry Andric llvm_unreachable("Invalid compound assignment type");
30610b57cec5SDimitry Andric }
3062480093f4SDimitry Andric if (AtomicOp != llvm::AtomicRMWInst::BAD_BINOP) {
3063480093f4SDimitry Andric llvm::Value *Amt = CGF.EmitToMemory(
30640b57cec5SDimitry Andric EmitScalarConversion(OpInfo.RHS, E->getRHS()->getType(), LHSTy,
30650b57cec5SDimitry Andric E->getExprLoc()),
30660b57cec5SDimitry Andric LHSTy);
3067480093f4SDimitry Andric Value *OldVal = Builder.CreateAtomicRMW(
3068480093f4SDimitry Andric AtomicOp, LHSLV.getPointer(CGF), Amt,
30690b57cec5SDimitry Andric llvm::AtomicOrdering::SequentiallyConsistent);
3070480093f4SDimitry Andric
3071480093f4SDimitry Andric // Since operation is atomic, the result type is guaranteed to be the
3072480093f4SDimitry Andric // same as the input in LLVM terms.
3073480093f4SDimitry Andric Result = Builder.CreateBinOp(Op, OldVal, Amt);
30740b57cec5SDimitry Andric return LHSLV;
30750b57cec5SDimitry Andric }
30760b57cec5SDimitry Andric }
30770b57cec5SDimitry Andric // FIXME: For floating point types, we should be saving and restoring the
30780b57cec5SDimitry Andric // floating point environment in the loop.
30790b57cec5SDimitry Andric llvm::BasicBlock *startBB = Builder.GetInsertBlock();
30800b57cec5SDimitry Andric llvm::BasicBlock *opBB = CGF.createBasicBlock("atomic_op", CGF.CurFn);
30810b57cec5SDimitry Andric OpInfo.LHS = EmitLoadOfLValue(LHSLV, E->getExprLoc());
30820b57cec5SDimitry Andric OpInfo.LHS = CGF.EmitToMemory(OpInfo.LHS, type);
30830b57cec5SDimitry Andric Builder.CreateBr(opBB);
30840b57cec5SDimitry Andric Builder.SetInsertPoint(opBB);
30850b57cec5SDimitry Andric atomicPHI = Builder.CreatePHI(OpInfo.LHS->getType(), 2);
30860b57cec5SDimitry Andric atomicPHI->addIncoming(OpInfo.LHS, startBB);
30870b57cec5SDimitry Andric OpInfo.LHS = atomicPHI;
30880b57cec5SDimitry Andric }
30890b57cec5SDimitry Andric else
30900b57cec5SDimitry Andric OpInfo.LHS = EmitLoadOfLValue(LHSLV, E->getExprLoc());
30910b57cec5SDimitry Andric
3092af732203SDimitry Andric CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, OpInfo.FPFeatures);
30930b57cec5SDimitry Andric SourceLocation Loc = E->getExprLoc();
30940b57cec5SDimitry Andric OpInfo.LHS =
30950b57cec5SDimitry Andric EmitScalarConversion(OpInfo.LHS, LHSTy, E->getComputationLHSType(), Loc);
30960b57cec5SDimitry Andric
30970b57cec5SDimitry Andric // Expand the binary operator.
30980b57cec5SDimitry Andric Result = (this->*Func)(OpInfo);
30990b57cec5SDimitry Andric
31000b57cec5SDimitry Andric // Convert the result back to the LHS type,
31010b57cec5SDimitry Andric // potentially with Implicit Conversion sanitizer check.
31020b57cec5SDimitry Andric Result = EmitScalarConversion(Result, E->getComputationResultType(), LHSTy,
31030b57cec5SDimitry Andric Loc, ScalarConversionOpts(CGF.SanOpts));
31040b57cec5SDimitry Andric
31050b57cec5SDimitry Andric if (atomicPHI) {
31060b57cec5SDimitry Andric llvm::BasicBlock *curBlock = Builder.GetInsertBlock();
31070b57cec5SDimitry Andric llvm::BasicBlock *contBB = CGF.createBasicBlock("atomic_cont", CGF.CurFn);
31080b57cec5SDimitry Andric auto Pair = CGF.EmitAtomicCompareExchange(
31090b57cec5SDimitry Andric LHSLV, RValue::get(atomicPHI), RValue::get(Result), E->getExprLoc());
31100b57cec5SDimitry Andric llvm::Value *old = CGF.EmitToMemory(Pair.first.getScalarVal(), LHSTy);
31110b57cec5SDimitry Andric llvm::Value *success = Pair.second;
31120b57cec5SDimitry Andric atomicPHI->addIncoming(old, curBlock);
31130b57cec5SDimitry Andric Builder.CreateCondBr(success, contBB, atomicPHI->getParent());
31140b57cec5SDimitry Andric Builder.SetInsertPoint(contBB);
31150b57cec5SDimitry Andric return LHSLV;
31160b57cec5SDimitry Andric }
31170b57cec5SDimitry Andric
31180b57cec5SDimitry Andric // Store the result value into the LHS lvalue. Bit-fields are handled
31190b57cec5SDimitry Andric // specially because the result is altered by the store, i.e., [C99 6.5.16p1]
31200b57cec5SDimitry Andric // 'An assignment expression has the value of the left operand after the
31210b57cec5SDimitry Andric // assignment...'.
31220b57cec5SDimitry Andric if (LHSLV.isBitField())
31230b57cec5SDimitry Andric CGF.EmitStoreThroughBitfieldLValue(RValue::get(Result), LHSLV, &Result);
31240b57cec5SDimitry Andric else
31250b57cec5SDimitry Andric CGF.EmitStoreThroughLValue(RValue::get(Result), LHSLV);
31260b57cec5SDimitry Andric
3127480093f4SDimitry Andric if (CGF.getLangOpts().OpenMP)
3128480093f4SDimitry Andric CGF.CGM.getOpenMPRuntime().checkAndEmitLastprivateConditional(CGF,
3129480093f4SDimitry Andric E->getLHS());
31300b57cec5SDimitry Andric return LHSLV;
31310b57cec5SDimitry Andric }
31320b57cec5SDimitry Andric
EmitCompoundAssign(const CompoundAssignOperator * E,Value * (ScalarExprEmitter::* Func)(const BinOpInfo &))31330b57cec5SDimitry Andric Value *ScalarExprEmitter::EmitCompoundAssign(const CompoundAssignOperator *E,
31340b57cec5SDimitry Andric Value *(ScalarExprEmitter::*Func)(const BinOpInfo &)) {
31350b57cec5SDimitry Andric bool Ignore = TestAndClearIgnoreResultAssign();
31360b57cec5SDimitry Andric Value *RHS = nullptr;
31370b57cec5SDimitry Andric LValue LHS = EmitCompoundAssignLValue(E, Func, RHS);
31380b57cec5SDimitry Andric
31390b57cec5SDimitry Andric // If the result is clearly ignored, return now.
31400b57cec5SDimitry Andric if (Ignore)
31410b57cec5SDimitry Andric return nullptr;
31420b57cec5SDimitry Andric
31430b57cec5SDimitry Andric // The result of an assignment in C is the assigned r-value.
31440b57cec5SDimitry Andric if (!CGF.getLangOpts().CPlusPlus)
31450b57cec5SDimitry Andric return RHS;
31460b57cec5SDimitry Andric
31470b57cec5SDimitry Andric // If the lvalue is non-volatile, return the computed value of the assignment.
31480b57cec5SDimitry Andric if (!LHS.isVolatileQualified())
31490b57cec5SDimitry Andric return RHS;
31500b57cec5SDimitry Andric
31510b57cec5SDimitry Andric // Otherwise, reload the value.
31520b57cec5SDimitry Andric return EmitLoadOfLValue(LHS, E->getExprLoc());
31530b57cec5SDimitry Andric }
31540b57cec5SDimitry Andric
EmitUndefinedBehaviorIntegerDivAndRemCheck(const BinOpInfo & Ops,llvm::Value * Zero,bool isDiv)31550b57cec5SDimitry Andric void ScalarExprEmitter::EmitUndefinedBehaviorIntegerDivAndRemCheck(
31560b57cec5SDimitry Andric const BinOpInfo &Ops, llvm::Value *Zero, bool isDiv) {
31570b57cec5SDimitry Andric SmallVector<std::pair<llvm::Value *, SanitizerMask>, 2> Checks;
31580b57cec5SDimitry Andric
31590b57cec5SDimitry Andric if (CGF.SanOpts.has(SanitizerKind::IntegerDivideByZero)) {
31600b57cec5SDimitry Andric Checks.push_back(std::make_pair(Builder.CreateICmpNE(Ops.RHS, Zero),
31610b57cec5SDimitry Andric SanitizerKind::IntegerDivideByZero));
31620b57cec5SDimitry Andric }
31630b57cec5SDimitry Andric
31640b57cec5SDimitry Andric const auto *BO = cast<BinaryOperator>(Ops.E);
31650b57cec5SDimitry Andric if (CGF.SanOpts.has(SanitizerKind::SignedIntegerOverflow) &&
31660b57cec5SDimitry Andric Ops.Ty->hasSignedIntegerRepresentation() &&
31670b57cec5SDimitry Andric !IsWidenedIntegerOp(CGF.getContext(), BO->getLHS()) &&
31680b57cec5SDimitry Andric Ops.mayHaveIntegerOverflow()) {
31690b57cec5SDimitry Andric llvm::IntegerType *Ty = cast<llvm::IntegerType>(Zero->getType());
31700b57cec5SDimitry Andric
31710b57cec5SDimitry Andric llvm::Value *IntMin =
31720b57cec5SDimitry Andric Builder.getInt(llvm::APInt::getSignedMinValue(Ty->getBitWidth()));
3173*5f7ddb14SDimitry Andric llvm::Value *NegOne = llvm::Constant::getAllOnesValue(Ty);
31740b57cec5SDimitry Andric
31750b57cec5SDimitry Andric llvm::Value *LHSCmp = Builder.CreateICmpNE(Ops.LHS, IntMin);
31760b57cec5SDimitry Andric llvm::Value *RHSCmp = Builder.CreateICmpNE(Ops.RHS, NegOne);
31770b57cec5SDimitry Andric llvm::Value *NotOverflow = Builder.CreateOr(LHSCmp, RHSCmp, "or");
31780b57cec5SDimitry Andric Checks.push_back(
31790b57cec5SDimitry Andric std::make_pair(NotOverflow, SanitizerKind::SignedIntegerOverflow));
31800b57cec5SDimitry Andric }
31810b57cec5SDimitry Andric
31820b57cec5SDimitry Andric if (Checks.size() > 0)
31830b57cec5SDimitry Andric EmitBinOpCheck(Checks, Ops);
31840b57cec5SDimitry Andric }
31850b57cec5SDimitry Andric
EmitDiv(const BinOpInfo & Ops)31860b57cec5SDimitry Andric Value *ScalarExprEmitter::EmitDiv(const BinOpInfo &Ops) {
31870b57cec5SDimitry Andric {
31880b57cec5SDimitry Andric CodeGenFunction::SanitizerScope SanScope(&CGF);
31890b57cec5SDimitry Andric if ((CGF.SanOpts.has(SanitizerKind::IntegerDivideByZero) ||
31900b57cec5SDimitry Andric CGF.SanOpts.has(SanitizerKind::SignedIntegerOverflow)) &&
31910b57cec5SDimitry Andric Ops.Ty->isIntegerType() &&
31920b57cec5SDimitry Andric (Ops.mayHaveIntegerDivisionByZero() || Ops.mayHaveIntegerOverflow())) {
31930b57cec5SDimitry Andric llvm::Value *Zero = llvm::Constant::getNullValue(ConvertType(Ops.Ty));
31940b57cec5SDimitry Andric EmitUndefinedBehaviorIntegerDivAndRemCheck(Ops, Zero, true);
31950b57cec5SDimitry Andric } else if (CGF.SanOpts.has(SanitizerKind::FloatDivideByZero) &&
31960b57cec5SDimitry Andric Ops.Ty->isRealFloatingType() &&
31970b57cec5SDimitry Andric Ops.mayHaveFloatDivisionByZero()) {
31980b57cec5SDimitry Andric llvm::Value *Zero = llvm::Constant::getNullValue(ConvertType(Ops.Ty));
31990b57cec5SDimitry Andric llvm::Value *NonZero = Builder.CreateFCmpUNE(Ops.RHS, Zero);
32000b57cec5SDimitry Andric EmitBinOpCheck(std::make_pair(NonZero, SanitizerKind::FloatDivideByZero),
32010b57cec5SDimitry Andric Ops);
32020b57cec5SDimitry Andric }
32030b57cec5SDimitry Andric }
32040b57cec5SDimitry Andric
3205*5f7ddb14SDimitry Andric if (Ops.Ty->isConstantMatrixType()) {
3206*5f7ddb14SDimitry Andric llvm::MatrixBuilder<CGBuilderTy> MB(Builder);
3207*5f7ddb14SDimitry Andric // We need to check the types of the operands of the operator to get the
3208*5f7ddb14SDimitry Andric // correct matrix dimensions.
3209*5f7ddb14SDimitry Andric auto *BO = cast<BinaryOperator>(Ops.E);
3210*5f7ddb14SDimitry Andric (void)BO;
3211*5f7ddb14SDimitry Andric assert(
3212*5f7ddb14SDimitry Andric isa<ConstantMatrixType>(BO->getLHS()->getType().getCanonicalType()) &&
3213*5f7ddb14SDimitry Andric "first operand must be a matrix");
3214*5f7ddb14SDimitry Andric assert(BO->getRHS()->getType().getCanonicalType()->isArithmeticType() &&
3215*5f7ddb14SDimitry Andric "second operand must be an arithmetic type");
3216*5f7ddb14SDimitry Andric CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, Ops.FPFeatures);
3217*5f7ddb14SDimitry Andric return MB.CreateScalarDiv(Ops.LHS, Ops.RHS,
3218*5f7ddb14SDimitry Andric Ops.Ty->hasUnsignedIntegerRepresentation());
3219*5f7ddb14SDimitry Andric }
3220*5f7ddb14SDimitry Andric
32210b57cec5SDimitry Andric if (Ops.LHS->getType()->isFPOrFPVectorTy()) {
32225ffd83dbSDimitry Andric llvm::Value *Val;
32235ffd83dbSDimitry Andric CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, Ops.FPFeatures);
32245ffd83dbSDimitry Andric Val = Builder.CreateFDiv(Ops.LHS, Ops.RHS, "div");
3225*5f7ddb14SDimitry Andric if ((CGF.getLangOpts().OpenCL &&
3226*5f7ddb14SDimitry Andric !CGF.CGM.getCodeGenOpts().OpenCLCorrectlyRoundedDivSqrt) ||
3227*5f7ddb14SDimitry Andric (CGF.getLangOpts().HIP && CGF.getLangOpts().CUDAIsDevice &&
3228*5f7ddb14SDimitry Andric !CGF.CGM.getCodeGenOpts().HIPCorrectlyRoundedDivSqrt)) {
32290b57cec5SDimitry Andric // OpenCL v1.1 s7.4: minimum accuracy of single precision / is 2.5ulp
32300b57cec5SDimitry Andric // OpenCL v1.2 s5.6.4.2: The -cl-fp32-correctly-rounded-divide-sqrt
32310b57cec5SDimitry Andric // build option allows an application to specify that single precision
32320b57cec5SDimitry Andric // floating-point divide (x/y and 1/x) and sqrt used in the program
32330b57cec5SDimitry Andric // source are correctly rounded.
32340b57cec5SDimitry Andric llvm::Type *ValTy = Val->getType();
32350b57cec5SDimitry Andric if (ValTy->isFloatTy() ||
32360b57cec5SDimitry Andric (isa<llvm::VectorType>(ValTy) &&
32370b57cec5SDimitry Andric cast<llvm::VectorType>(ValTy)->getElementType()->isFloatTy()))
32380b57cec5SDimitry Andric CGF.SetFPAccuracy(Val, 2.5);
32390b57cec5SDimitry Andric }
32400b57cec5SDimitry Andric return Val;
32410b57cec5SDimitry Andric }
32425ffd83dbSDimitry Andric else if (Ops.isFixedPointOp())
32435ffd83dbSDimitry Andric return EmitFixedPointBinOp(Ops);
32440b57cec5SDimitry Andric else if (Ops.Ty->hasUnsignedIntegerRepresentation())
32450b57cec5SDimitry Andric return Builder.CreateUDiv(Ops.LHS, Ops.RHS, "div");
32460b57cec5SDimitry Andric else
32470b57cec5SDimitry Andric return Builder.CreateSDiv(Ops.LHS, Ops.RHS, "div");
32480b57cec5SDimitry Andric }
32490b57cec5SDimitry Andric
EmitRem(const BinOpInfo & Ops)32500b57cec5SDimitry Andric Value *ScalarExprEmitter::EmitRem(const BinOpInfo &Ops) {
32510b57cec5SDimitry Andric // Rem in C can't be a floating point type: C99 6.5.5p2.
32520b57cec5SDimitry Andric if ((CGF.SanOpts.has(SanitizerKind::IntegerDivideByZero) ||
32530b57cec5SDimitry Andric CGF.SanOpts.has(SanitizerKind::SignedIntegerOverflow)) &&
32540b57cec5SDimitry Andric Ops.Ty->isIntegerType() &&
32550b57cec5SDimitry Andric (Ops.mayHaveIntegerDivisionByZero() || Ops.mayHaveIntegerOverflow())) {
32560b57cec5SDimitry Andric CodeGenFunction::SanitizerScope SanScope(&CGF);
32570b57cec5SDimitry Andric llvm::Value *Zero = llvm::Constant::getNullValue(ConvertType(Ops.Ty));
32580b57cec5SDimitry Andric EmitUndefinedBehaviorIntegerDivAndRemCheck(Ops, Zero, false);
32590b57cec5SDimitry Andric }
32600b57cec5SDimitry Andric
32610b57cec5SDimitry Andric if (Ops.Ty->hasUnsignedIntegerRepresentation())
32620b57cec5SDimitry Andric return Builder.CreateURem(Ops.LHS, Ops.RHS, "rem");
32630b57cec5SDimitry Andric else
32640b57cec5SDimitry Andric return Builder.CreateSRem(Ops.LHS, Ops.RHS, "rem");
32650b57cec5SDimitry Andric }
32660b57cec5SDimitry Andric
EmitOverflowCheckedBinOp(const BinOpInfo & Ops)32670b57cec5SDimitry Andric Value *ScalarExprEmitter::EmitOverflowCheckedBinOp(const BinOpInfo &Ops) {
32680b57cec5SDimitry Andric unsigned IID;
32690b57cec5SDimitry Andric unsigned OpID = 0;
3270af732203SDimitry Andric SanitizerHandler OverflowKind;
32710b57cec5SDimitry Andric
32720b57cec5SDimitry Andric bool isSigned = Ops.Ty->isSignedIntegerOrEnumerationType();
32730b57cec5SDimitry Andric switch (Ops.Opcode) {
32740b57cec5SDimitry Andric case BO_Add:
32750b57cec5SDimitry Andric case BO_AddAssign:
32760b57cec5SDimitry Andric OpID = 1;
32770b57cec5SDimitry Andric IID = isSigned ? llvm::Intrinsic::sadd_with_overflow :
32780b57cec5SDimitry Andric llvm::Intrinsic::uadd_with_overflow;
3279af732203SDimitry Andric OverflowKind = SanitizerHandler::AddOverflow;
32800b57cec5SDimitry Andric break;
32810b57cec5SDimitry Andric case BO_Sub:
32820b57cec5SDimitry Andric case BO_SubAssign:
32830b57cec5SDimitry Andric OpID = 2;
32840b57cec5SDimitry Andric IID = isSigned ? llvm::Intrinsic::ssub_with_overflow :
32850b57cec5SDimitry Andric llvm::Intrinsic::usub_with_overflow;
3286af732203SDimitry Andric OverflowKind = SanitizerHandler::SubOverflow;
32870b57cec5SDimitry Andric break;
32880b57cec5SDimitry Andric case BO_Mul:
32890b57cec5SDimitry Andric case BO_MulAssign:
32900b57cec5SDimitry Andric OpID = 3;
32910b57cec5SDimitry Andric IID = isSigned ? llvm::Intrinsic::smul_with_overflow :
32920b57cec5SDimitry Andric llvm::Intrinsic::umul_with_overflow;
3293af732203SDimitry Andric OverflowKind = SanitizerHandler::MulOverflow;
32940b57cec5SDimitry Andric break;
32950b57cec5SDimitry Andric default:
32960b57cec5SDimitry Andric llvm_unreachable("Unsupported operation for overflow detection");
32970b57cec5SDimitry Andric }
32980b57cec5SDimitry Andric OpID <<= 1;
32990b57cec5SDimitry Andric if (isSigned)
33000b57cec5SDimitry Andric OpID |= 1;
33010b57cec5SDimitry Andric
33020b57cec5SDimitry Andric CodeGenFunction::SanitizerScope SanScope(&CGF);
33030b57cec5SDimitry Andric llvm::Type *opTy = CGF.CGM.getTypes().ConvertType(Ops.Ty);
33040b57cec5SDimitry Andric
33050b57cec5SDimitry Andric llvm::Function *intrinsic = CGF.CGM.getIntrinsic(IID, opTy);
33060b57cec5SDimitry Andric
33070b57cec5SDimitry Andric Value *resultAndOverflow = Builder.CreateCall(intrinsic, {Ops.LHS, Ops.RHS});
33080b57cec5SDimitry Andric Value *result = Builder.CreateExtractValue(resultAndOverflow, 0);
33090b57cec5SDimitry Andric Value *overflow = Builder.CreateExtractValue(resultAndOverflow, 1);
33100b57cec5SDimitry Andric
33110b57cec5SDimitry Andric // Handle overflow with llvm.trap if no custom handler has been specified.
33120b57cec5SDimitry Andric const std::string *handlerName =
33130b57cec5SDimitry Andric &CGF.getLangOpts().OverflowHandler;
33140b57cec5SDimitry Andric if (handlerName->empty()) {
33150b57cec5SDimitry Andric // If the signed-integer-overflow sanitizer is enabled, emit a call to its
33160b57cec5SDimitry Andric // runtime. Otherwise, this is a -ftrapv check, so just emit a trap.
33170b57cec5SDimitry Andric if (!isSigned || CGF.SanOpts.has(SanitizerKind::SignedIntegerOverflow)) {
33180b57cec5SDimitry Andric llvm::Value *NotOverflow = Builder.CreateNot(overflow);
33190b57cec5SDimitry Andric SanitizerMask Kind = isSigned ? SanitizerKind::SignedIntegerOverflow
33200b57cec5SDimitry Andric : SanitizerKind::UnsignedIntegerOverflow;
33210b57cec5SDimitry Andric EmitBinOpCheck(std::make_pair(NotOverflow, Kind), Ops);
33220b57cec5SDimitry Andric } else
3323af732203SDimitry Andric CGF.EmitTrapCheck(Builder.CreateNot(overflow), OverflowKind);
33240b57cec5SDimitry Andric return result;
33250b57cec5SDimitry Andric }
33260b57cec5SDimitry Andric
33270b57cec5SDimitry Andric // Branch in case of overflow.
33280b57cec5SDimitry Andric llvm::BasicBlock *initialBB = Builder.GetInsertBlock();
33290b57cec5SDimitry Andric llvm::BasicBlock *continueBB =
33300b57cec5SDimitry Andric CGF.createBasicBlock("nooverflow", CGF.CurFn, initialBB->getNextNode());
33310b57cec5SDimitry Andric llvm::BasicBlock *overflowBB = CGF.createBasicBlock("overflow", CGF.CurFn);
33320b57cec5SDimitry Andric
33330b57cec5SDimitry Andric Builder.CreateCondBr(overflow, overflowBB, continueBB);
33340b57cec5SDimitry Andric
33350b57cec5SDimitry Andric // If an overflow handler is set, then we want to call it and then use its
33360b57cec5SDimitry Andric // result, if it returns.
33370b57cec5SDimitry Andric Builder.SetInsertPoint(overflowBB);
33380b57cec5SDimitry Andric
33390b57cec5SDimitry Andric // Get the overflow handler.
33400b57cec5SDimitry Andric llvm::Type *Int8Ty = CGF.Int8Ty;
33410b57cec5SDimitry Andric llvm::Type *argTypes[] = { CGF.Int64Ty, CGF.Int64Ty, Int8Ty, Int8Ty };
33420b57cec5SDimitry Andric llvm::FunctionType *handlerTy =
33430b57cec5SDimitry Andric llvm::FunctionType::get(CGF.Int64Ty, argTypes, true);
33440b57cec5SDimitry Andric llvm::FunctionCallee handler =
33450b57cec5SDimitry Andric CGF.CGM.CreateRuntimeFunction(handlerTy, *handlerName);
33460b57cec5SDimitry Andric
33470b57cec5SDimitry Andric // Sign extend the args to 64-bit, so that we can use the same handler for
33480b57cec5SDimitry Andric // all types of overflow.
33490b57cec5SDimitry Andric llvm::Value *lhs = Builder.CreateSExt(Ops.LHS, CGF.Int64Ty);
33500b57cec5SDimitry Andric llvm::Value *rhs = Builder.CreateSExt(Ops.RHS, CGF.Int64Ty);
33510b57cec5SDimitry Andric
33520b57cec5SDimitry Andric // Call the handler with the two arguments, the operation, and the size of
33530b57cec5SDimitry Andric // the result.
33540b57cec5SDimitry Andric llvm::Value *handlerArgs[] = {
33550b57cec5SDimitry Andric lhs,
33560b57cec5SDimitry Andric rhs,
33570b57cec5SDimitry Andric Builder.getInt8(OpID),
33580b57cec5SDimitry Andric Builder.getInt8(cast<llvm::IntegerType>(opTy)->getBitWidth())
33590b57cec5SDimitry Andric };
33600b57cec5SDimitry Andric llvm::Value *handlerResult =
33610b57cec5SDimitry Andric CGF.EmitNounwindRuntimeCall(handler, handlerArgs);
33620b57cec5SDimitry Andric
33630b57cec5SDimitry Andric // Truncate the result back to the desired size.
33640b57cec5SDimitry Andric handlerResult = Builder.CreateTrunc(handlerResult, opTy);
33650b57cec5SDimitry Andric Builder.CreateBr(continueBB);
33660b57cec5SDimitry Andric
33670b57cec5SDimitry Andric Builder.SetInsertPoint(continueBB);
33680b57cec5SDimitry Andric llvm::PHINode *phi = Builder.CreatePHI(opTy, 2);
33690b57cec5SDimitry Andric phi->addIncoming(result, initialBB);
33700b57cec5SDimitry Andric phi->addIncoming(handlerResult, overflowBB);
33710b57cec5SDimitry Andric
33720b57cec5SDimitry Andric return phi;
33730b57cec5SDimitry Andric }
33740b57cec5SDimitry Andric
33750b57cec5SDimitry Andric /// Emit pointer + index arithmetic.
emitPointerArithmetic(CodeGenFunction & CGF,const BinOpInfo & op,bool isSubtraction)33760b57cec5SDimitry Andric static Value *emitPointerArithmetic(CodeGenFunction &CGF,
33770b57cec5SDimitry Andric const BinOpInfo &op,
33780b57cec5SDimitry Andric bool isSubtraction) {
33790b57cec5SDimitry Andric // Must have binary (not unary) expr here. Unary pointer
33800b57cec5SDimitry Andric // increment/decrement doesn't use this path.
33810b57cec5SDimitry Andric const BinaryOperator *expr = cast<BinaryOperator>(op.E);
33820b57cec5SDimitry Andric
33830b57cec5SDimitry Andric Value *pointer = op.LHS;
33840b57cec5SDimitry Andric Expr *pointerOperand = expr->getLHS();
33850b57cec5SDimitry Andric Value *index = op.RHS;
33860b57cec5SDimitry Andric Expr *indexOperand = expr->getRHS();
33870b57cec5SDimitry Andric
33880b57cec5SDimitry Andric // In a subtraction, the LHS is always the pointer.
33890b57cec5SDimitry Andric if (!isSubtraction && !pointer->getType()->isPointerTy()) {
33900b57cec5SDimitry Andric std::swap(pointer, index);
33910b57cec5SDimitry Andric std::swap(pointerOperand, indexOperand);
33920b57cec5SDimitry Andric }
33930b57cec5SDimitry Andric
33940b57cec5SDimitry Andric bool isSigned = indexOperand->getType()->isSignedIntegerOrEnumerationType();
33950b57cec5SDimitry Andric
33960b57cec5SDimitry Andric unsigned width = cast<llvm::IntegerType>(index->getType())->getBitWidth();
33970b57cec5SDimitry Andric auto &DL = CGF.CGM.getDataLayout();
33980b57cec5SDimitry Andric auto PtrTy = cast<llvm::PointerType>(pointer->getType());
33990b57cec5SDimitry Andric
34000b57cec5SDimitry Andric // Some versions of glibc and gcc use idioms (particularly in their malloc
34010b57cec5SDimitry Andric // routines) that add a pointer-sized integer (known to be a pointer value)
34020b57cec5SDimitry Andric // to a null pointer in order to cast the value back to an integer or as
34030b57cec5SDimitry Andric // part of a pointer alignment algorithm. This is undefined behavior, but
34040b57cec5SDimitry Andric // we'd like to be able to compile programs that use it.
34050b57cec5SDimitry Andric //
34060b57cec5SDimitry Andric // Normally, we'd generate a GEP with a null-pointer base here in response
34070b57cec5SDimitry Andric // to that code, but it's also UB to dereference a pointer created that
34080b57cec5SDimitry Andric // way. Instead (as an acknowledged hack to tolerate the idiom) we will
34090b57cec5SDimitry Andric // generate a direct cast of the integer value to a pointer.
34100b57cec5SDimitry Andric //
34110b57cec5SDimitry Andric // The idiom (p = nullptr + N) is not met if any of the following are true:
34120b57cec5SDimitry Andric //
34130b57cec5SDimitry Andric // The operation is subtraction.
34140b57cec5SDimitry Andric // The index is not pointer-sized.
34150b57cec5SDimitry Andric // The pointer type is not byte-sized.
34160b57cec5SDimitry Andric //
34170b57cec5SDimitry Andric if (BinaryOperator::isNullPointerArithmeticExtension(CGF.getContext(),
34180b57cec5SDimitry Andric op.Opcode,
34190b57cec5SDimitry Andric expr->getLHS(),
34200b57cec5SDimitry Andric expr->getRHS()))
34210b57cec5SDimitry Andric return CGF.Builder.CreateIntToPtr(index, pointer->getType());
34220b57cec5SDimitry Andric
3423480093f4SDimitry Andric if (width != DL.getIndexTypeSizeInBits(PtrTy)) {
34240b57cec5SDimitry Andric // Zero-extend or sign-extend the pointer value according to
34250b57cec5SDimitry Andric // whether the index is signed or not.
3426480093f4SDimitry Andric index = CGF.Builder.CreateIntCast(index, DL.getIndexType(PtrTy), isSigned,
34270b57cec5SDimitry Andric "idx.ext");
34280b57cec5SDimitry Andric }
34290b57cec5SDimitry Andric
34300b57cec5SDimitry Andric // If this is subtraction, negate the index.
34310b57cec5SDimitry Andric if (isSubtraction)
34320b57cec5SDimitry Andric index = CGF.Builder.CreateNeg(index, "idx.neg");
34330b57cec5SDimitry Andric
34340b57cec5SDimitry Andric if (CGF.SanOpts.has(SanitizerKind::ArrayBounds))
34350b57cec5SDimitry Andric CGF.EmitBoundsCheck(op.E, pointerOperand, index, indexOperand->getType(),
34360b57cec5SDimitry Andric /*Accessed*/ false);
34370b57cec5SDimitry Andric
34380b57cec5SDimitry Andric const PointerType *pointerType
34390b57cec5SDimitry Andric = pointerOperand->getType()->getAs<PointerType>();
34400b57cec5SDimitry Andric if (!pointerType) {
34410b57cec5SDimitry Andric QualType objectType = pointerOperand->getType()
34420b57cec5SDimitry Andric ->castAs<ObjCObjectPointerType>()
34430b57cec5SDimitry Andric ->getPointeeType();
34440b57cec5SDimitry Andric llvm::Value *objectSize
34450b57cec5SDimitry Andric = CGF.CGM.getSize(CGF.getContext().getTypeSizeInChars(objectType));
34460b57cec5SDimitry Andric
34470b57cec5SDimitry Andric index = CGF.Builder.CreateMul(index, objectSize);
34480b57cec5SDimitry Andric
34490b57cec5SDimitry Andric Value *result = CGF.Builder.CreateBitCast(pointer, CGF.VoidPtrTy);
3450*5f7ddb14SDimitry Andric result = CGF.Builder.CreateGEP(CGF.Int8Ty, result, index, "add.ptr");
34510b57cec5SDimitry Andric return CGF.Builder.CreateBitCast(result, pointer->getType());
34520b57cec5SDimitry Andric }
34530b57cec5SDimitry Andric
34540b57cec5SDimitry Andric QualType elementType = pointerType->getPointeeType();
34550b57cec5SDimitry Andric if (const VariableArrayType *vla
34560b57cec5SDimitry Andric = CGF.getContext().getAsVariableArrayType(elementType)) {
34570b57cec5SDimitry Andric // The element count here is the total number of non-VLA elements.
34580b57cec5SDimitry Andric llvm::Value *numElements = CGF.getVLASize(vla).NumElts;
34590b57cec5SDimitry Andric
34600b57cec5SDimitry Andric // Effectively, the multiply by the VLA size is part of the GEP.
34610b57cec5SDimitry Andric // GEP indexes are signed, and scaling an index isn't permitted to
34620b57cec5SDimitry Andric // signed-overflow, so we use the same semantics for our explicit
34630b57cec5SDimitry Andric // multiply. We suppress this if overflow is not undefined behavior.
34640b57cec5SDimitry Andric if (CGF.getLangOpts().isSignedOverflowDefined()) {
34650b57cec5SDimitry Andric index = CGF.Builder.CreateMul(index, numElements, "vla.index");
3466*5f7ddb14SDimitry Andric pointer = CGF.Builder.CreateGEP(
3467*5f7ddb14SDimitry Andric pointer->getType()->getPointerElementType(), pointer, index,
3468*5f7ddb14SDimitry Andric "add.ptr");
34690b57cec5SDimitry Andric } else {
34700b57cec5SDimitry Andric index = CGF.Builder.CreateNSWMul(index, numElements, "vla.index");
34710b57cec5SDimitry Andric pointer =
34720b57cec5SDimitry Andric CGF.EmitCheckedInBoundsGEP(pointer, index, isSigned, isSubtraction,
34730b57cec5SDimitry Andric op.E->getExprLoc(), "add.ptr");
34740b57cec5SDimitry Andric }
34750b57cec5SDimitry Andric return pointer;
34760b57cec5SDimitry Andric }
34770b57cec5SDimitry Andric
34780b57cec5SDimitry Andric // Explicitly handle GNU void* and function pointer arithmetic extensions. The
34790b57cec5SDimitry Andric // GNU void* casts amount to no-ops since our void* type is i8*, but this is
34800b57cec5SDimitry Andric // future proof.
34810b57cec5SDimitry Andric if (elementType->isVoidType() || elementType->isFunctionType()) {
3482480093f4SDimitry Andric Value *result = CGF.EmitCastToVoidPtr(pointer);
3483*5f7ddb14SDimitry Andric result = CGF.Builder.CreateGEP(CGF.Int8Ty, result, index, "add.ptr");
34840b57cec5SDimitry Andric return CGF.Builder.CreateBitCast(result, pointer->getType());
34850b57cec5SDimitry Andric }
34860b57cec5SDimitry Andric
34870b57cec5SDimitry Andric if (CGF.getLangOpts().isSignedOverflowDefined())
3488*5f7ddb14SDimitry Andric return CGF.Builder.CreateGEP(
3489*5f7ddb14SDimitry Andric pointer->getType()->getPointerElementType(), pointer, index, "add.ptr");
34900b57cec5SDimitry Andric
34910b57cec5SDimitry Andric return CGF.EmitCheckedInBoundsGEP(pointer, index, isSigned, isSubtraction,
34920b57cec5SDimitry Andric op.E->getExprLoc(), "add.ptr");
34930b57cec5SDimitry Andric }
34940b57cec5SDimitry Andric
34950b57cec5SDimitry Andric // Construct an fmuladd intrinsic to represent a fused mul-add of MulOp and
34960b57cec5SDimitry Andric // Addend. Use negMul and negAdd to negate the first operand of the Mul or
34970b57cec5SDimitry Andric // the add operand respectively. This allows fmuladd to represent a*b-c, or
34980b57cec5SDimitry Andric // c-a*b. Patterns in LLVM should catch the negated forms and translate them to
34990b57cec5SDimitry Andric // efficient operations.
buildFMulAdd(llvm::Instruction * MulOp,Value * Addend,const CodeGenFunction & CGF,CGBuilderTy & Builder,bool negMul,bool negAdd)35005ffd83dbSDimitry Andric static Value* buildFMulAdd(llvm::Instruction *MulOp, Value *Addend,
35010b57cec5SDimitry Andric const CodeGenFunction &CGF, CGBuilderTy &Builder,
35020b57cec5SDimitry Andric bool negMul, bool negAdd) {
35030b57cec5SDimitry Andric assert(!(negMul && negAdd) && "Only one of negMul and negAdd should be set.");
35040b57cec5SDimitry Andric
35050b57cec5SDimitry Andric Value *MulOp0 = MulOp->getOperand(0);
35060b57cec5SDimitry Andric Value *MulOp1 = MulOp->getOperand(1);
3507480093f4SDimitry Andric if (negMul)
3508480093f4SDimitry Andric MulOp0 = Builder.CreateFNeg(MulOp0, "neg");
3509480093f4SDimitry Andric if (negAdd)
3510480093f4SDimitry Andric Addend = Builder.CreateFNeg(Addend, "neg");
35110b57cec5SDimitry Andric
35125ffd83dbSDimitry Andric Value *FMulAdd = nullptr;
35135ffd83dbSDimitry Andric if (Builder.getIsFPConstrained()) {
35145ffd83dbSDimitry Andric assert(isa<llvm::ConstrainedFPIntrinsic>(MulOp) &&
35155ffd83dbSDimitry Andric "Only constrained operation should be created when Builder is in FP "
35165ffd83dbSDimitry Andric "constrained mode");
35175ffd83dbSDimitry Andric FMulAdd = Builder.CreateConstrainedFPCall(
35185ffd83dbSDimitry Andric CGF.CGM.getIntrinsic(llvm::Intrinsic::experimental_constrained_fmuladd,
35195ffd83dbSDimitry Andric Addend->getType()),
35205ffd83dbSDimitry Andric {MulOp0, MulOp1, Addend});
35215ffd83dbSDimitry Andric } else {
35225ffd83dbSDimitry Andric FMulAdd = Builder.CreateCall(
35230b57cec5SDimitry Andric CGF.CGM.getIntrinsic(llvm::Intrinsic::fmuladd, Addend->getType()),
35240b57cec5SDimitry Andric {MulOp0, MulOp1, Addend});
35255ffd83dbSDimitry Andric }
35260b57cec5SDimitry Andric MulOp->eraseFromParent();
35270b57cec5SDimitry Andric
35280b57cec5SDimitry Andric return FMulAdd;
35290b57cec5SDimitry Andric }
35300b57cec5SDimitry Andric
35310b57cec5SDimitry Andric // Check whether it would be legal to emit an fmuladd intrinsic call to
35320b57cec5SDimitry Andric // represent op and if so, build the fmuladd.
35330b57cec5SDimitry Andric //
35340b57cec5SDimitry Andric // Checks that (a) the operation is fusable, and (b) -ffp-contract=on.
35350b57cec5SDimitry Andric // Does NOT check the type of the operation - it's assumed that this function
35360b57cec5SDimitry 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)35370b57cec5SDimitry Andric static Value* tryEmitFMulAdd(const BinOpInfo &op,
35380b57cec5SDimitry Andric const CodeGenFunction &CGF, CGBuilderTy &Builder,
35390b57cec5SDimitry Andric bool isSub=false) {
35400b57cec5SDimitry Andric
35410b57cec5SDimitry Andric assert((op.Opcode == BO_Add || op.Opcode == BO_AddAssign ||
35420b57cec5SDimitry Andric op.Opcode == BO_Sub || op.Opcode == BO_SubAssign) &&
35430b57cec5SDimitry Andric "Only fadd/fsub can be the root of an fmuladd.");
35440b57cec5SDimitry Andric
35450b57cec5SDimitry Andric // Check whether this op is marked as fusable.
35460b57cec5SDimitry Andric if (!op.FPFeatures.allowFPContractWithinStatement())
35470b57cec5SDimitry Andric return nullptr;
35480b57cec5SDimitry Andric
35490b57cec5SDimitry Andric // We have a potentially fusable op. Look for a mul on one of the operands.
35500b57cec5SDimitry Andric // Also, make sure that the mul result isn't used directly. In that case,
35510b57cec5SDimitry Andric // there's no point creating a muladd operation.
35520b57cec5SDimitry Andric if (auto *LHSBinOp = dyn_cast<llvm::BinaryOperator>(op.LHS)) {
35530b57cec5SDimitry Andric if (LHSBinOp->getOpcode() == llvm::Instruction::FMul &&
35540b57cec5SDimitry Andric LHSBinOp->use_empty())
35550b57cec5SDimitry Andric return buildFMulAdd(LHSBinOp, op.RHS, CGF, Builder, false, isSub);
35560b57cec5SDimitry Andric }
35570b57cec5SDimitry Andric if (auto *RHSBinOp = dyn_cast<llvm::BinaryOperator>(op.RHS)) {
35580b57cec5SDimitry Andric if (RHSBinOp->getOpcode() == llvm::Instruction::FMul &&
35590b57cec5SDimitry Andric RHSBinOp->use_empty())
35600b57cec5SDimitry Andric return buildFMulAdd(RHSBinOp, op.LHS, CGF, Builder, isSub, false);
35610b57cec5SDimitry Andric }
35620b57cec5SDimitry Andric
35635ffd83dbSDimitry Andric if (auto *LHSBinOp = dyn_cast<llvm::CallBase>(op.LHS)) {
35645ffd83dbSDimitry Andric if (LHSBinOp->getIntrinsicID() ==
35655ffd83dbSDimitry Andric llvm::Intrinsic::experimental_constrained_fmul &&
35665ffd83dbSDimitry Andric LHSBinOp->use_empty())
35675ffd83dbSDimitry Andric return buildFMulAdd(LHSBinOp, op.RHS, CGF, Builder, false, isSub);
35685ffd83dbSDimitry Andric }
35695ffd83dbSDimitry Andric if (auto *RHSBinOp = dyn_cast<llvm::CallBase>(op.RHS)) {
35705ffd83dbSDimitry Andric if (RHSBinOp->getIntrinsicID() ==
35715ffd83dbSDimitry Andric llvm::Intrinsic::experimental_constrained_fmul &&
35725ffd83dbSDimitry Andric RHSBinOp->use_empty())
35735ffd83dbSDimitry Andric return buildFMulAdd(RHSBinOp, op.LHS, CGF, Builder, isSub, false);
35745ffd83dbSDimitry Andric }
35755ffd83dbSDimitry Andric
35760b57cec5SDimitry Andric return nullptr;
35770b57cec5SDimitry Andric }
35780b57cec5SDimitry Andric
EmitAdd(const BinOpInfo & op)35790b57cec5SDimitry Andric Value *ScalarExprEmitter::EmitAdd(const BinOpInfo &op) {
35800b57cec5SDimitry Andric if (op.LHS->getType()->isPointerTy() ||
35810b57cec5SDimitry Andric op.RHS->getType()->isPointerTy())
35820b57cec5SDimitry Andric return emitPointerArithmetic(CGF, op, CodeGenFunction::NotSubtraction);
35830b57cec5SDimitry Andric
35840b57cec5SDimitry Andric if (op.Ty->isSignedIntegerOrEnumerationType()) {
35850b57cec5SDimitry Andric switch (CGF.getLangOpts().getSignedOverflowBehavior()) {
35860b57cec5SDimitry Andric case LangOptions::SOB_Defined:
35870b57cec5SDimitry Andric return Builder.CreateAdd(op.LHS, op.RHS, "add");
35880b57cec5SDimitry Andric case LangOptions::SOB_Undefined:
35890b57cec5SDimitry Andric if (!CGF.SanOpts.has(SanitizerKind::SignedIntegerOverflow))
35900b57cec5SDimitry Andric return Builder.CreateNSWAdd(op.LHS, op.RHS, "add");
35910b57cec5SDimitry Andric LLVM_FALLTHROUGH;
35920b57cec5SDimitry Andric case LangOptions::SOB_Trapping:
35930b57cec5SDimitry Andric if (CanElideOverflowCheck(CGF.getContext(), op))
35940b57cec5SDimitry Andric return Builder.CreateNSWAdd(op.LHS, op.RHS, "add");
35950b57cec5SDimitry Andric return EmitOverflowCheckedBinOp(op);
35960b57cec5SDimitry Andric }
35970b57cec5SDimitry Andric }
35980b57cec5SDimitry Andric
35995ffd83dbSDimitry Andric if (op.Ty->isConstantMatrixType()) {
36005ffd83dbSDimitry Andric llvm::MatrixBuilder<CGBuilderTy> MB(Builder);
3601*5f7ddb14SDimitry Andric CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, op.FPFeatures);
36025ffd83dbSDimitry Andric return MB.CreateAdd(op.LHS, op.RHS);
36035ffd83dbSDimitry Andric }
36045ffd83dbSDimitry Andric
36050b57cec5SDimitry Andric if (op.Ty->isUnsignedIntegerType() &&
36060b57cec5SDimitry Andric CGF.SanOpts.has(SanitizerKind::UnsignedIntegerOverflow) &&
36070b57cec5SDimitry Andric !CanElideOverflowCheck(CGF.getContext(), op))
36080b57cec5SDimitry Andric return EmitOverflowCheckedBinOp(op);
36090b57cec5SDimitry Andric
36100b57cec5SDimitry Andric if (op.LHS->getType()->isFPOrFPVectorTy()) {
36115ffd83dbSDimitry Andric CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, op.FPFeatures);
36120b57cec5SDimitry Andric // Try to form an fmuladd.
36130b57cec5SDimitry Andric if (Value *FMulAdd = tryEmitFMulAdd(op, CGF, Builder))
36140b57cec5SDimitry Andric return FMulAdd;
36150b57cec5SDimitry Andric
36165ffd83dbSDimitry Andric return Builder.CreateFAdd(op.LHS, op.RHS, "add");
36170b57cec5SDimitry Andric }
36180b57cec5SDimitry Andric
36195ffd83dbSDimitry Andric if (op.isFixedPointOp())
36200b57cec5SDimitry Andric return EmitFixedPointBinOp(op);
36210b57cec5SDimitry Andric
36220b57cec5SDimitry Andric return Builder.CreateAdd(op.LHS, op.RHS, "add");
36230b57cec5SDimitry Andric }
36240b57cec5SDimitry Andric
36250b57cec5SDimitry Andric /// The resulting value must be calculated with exact precision, so the operands
36260b57cec5SDimitry Andric /// may not be the same type.
EmitFixedPointBinOp(const BinOpInfo & op)36270b57cec5SDimitry Andric Value *ScalarExprEmitter::EmitFixedPointBinOp(const BinOpInfo &op) {
36280b57cec5SDimitry Andric using llvm::APSInt;
36290b57cec5SDimitry Andric using llvm::ConstantInt;
36300b57cec5SDimitry Andric
36315ffd83dbSDimitry Andric // This is either a binary operation where at least one of the operands is
36325ffd83dbSDimitry Andric // a fixed-point type, or a unary operation where the operand is a fixed-point
36335ffd83dbSDimitry Andric // type. The result type of a binary operation is determined by
36345ffd83dbSDimitry Andric // Sema::handleFixedPointConversions().
36350b57cec5SDimitry Andric QualType ResultTy = op.Ty;
36365ffd83dbSDimitry Andric QualType LHSTy, RHSTy;
36375ffd83dbSDimitry Andric if (const auto *BinOp = dyn_cast<BinaryOperator>(op.E)) {
36385ffd83dbSDimitry Andric RHSTy = BinOp->getRHS()->getType();
36395ffd83dbSDimitry Andric if (const auto *CAO = dyn_cast<CompoundAssignOperator>(BinOp)) {
36405ffd83dbSDimitry Andric // For compound assignment, the effective type of the LHS at this point
36415ffd83dbSDimitry Andric // is the computation LHS type, not the actual LHS type, and the final
36425ffd83dbSDimitry Andric // result type is not the type of the expression but rather the
36435ffd83dbSDimitry Andric // computation result type.
36445ffd83dbSDimitry Andric LHSTy = CAO->getComputationLHSType();
36455ffd83dbSDimitry Andric ResultTy = CAO->getComputationResultType();
36465ffd83dbSDimitry Andric } else
36475ffd83dbSDimitry Andric LHSTy = BinOp->getLHS()->getType();
36485ffd83dbSDimitry Andric } else if (const auto *UnOp = dyn_cast<UnaryOperator>(op.E)) {
36495ffd83dbSDimitry Andric LHSTy = UnOp->getSubExpr()->getType();
36505ffd83dbSDimitry Andric RHSTy = UnOp->getSubExpr()->getType();
36515ffd83dbSDimitry Andric }
36520b57cec5SDimitry Andric ASTContext &Ctx = CGF.getContext();
36530b57cec5SDimitry Andric Value *LHS = op.LHS;
36540b57cec5SDimitry Andric Value *RHS = op.RHS;
36550b57cec5SDimitry Andric
36560b57cec5SDimitry Andric auto LHSFixedSema = Ctx.getFixedPointSemantics(LHSTy);
36570b57cec5SDimitry Andric auto RHSFixedSema = Ctx.getFixedPointSemantics(RHSTy);
36580b57cec5SDimitry Andric auto ResultFixedSema = Ctx.getFixedPointSemantics(ResultTy);
36590b57cec5SDimitry Andric auto CommonFixedSema = LHSFixedSema.getCommonSemantics(RHSFixedSema);
36600b57cec5SDimitry Andric
36615ffd83dbSDimitry Andric // Perform the actual operation.
36620b57cec5SDimitry Andric Value *Result;
3663af732203SDimitry Andric llvm::FixedPointBuilder<CGBuilderTy> FPBuilder(Builder);
36645ffd83dbSDimitry Andric switch (op.Opcode) {
36655ffd83dbSDimitry Andric case BO_AddAssign:
3666af732203SDimitry Andric case BO_Add:
3667af732203SDimitry Andric Result = FPBuilder.CreateAdd(LHS, LHSFixedSema, RHS, RHSFixedSema);
36680b57cec5SDimitry Andric break;
36695ffd83dbSDimitry Andric case BO_SubAssign:
3670af732203SDimitry Andric case BO_Sub:
3671af732203SDimitry Andric Result = FPBuilder.CreateSub(LHS, LHSFixedSema, RHS, RHSFixedSema);
36720b57cec5SDimitry Andric break;
36735ffd83dbSDimitry Andric case BO_MulAssign:
3674af732203SDimitry Andric case BO_Mul:
3675af732203SDimitry Andric Result = FPBuilder.CreateMul(LHS, LHSFixedSema, RHS, RHSFixedSema);
36765ffd83dbSDimitry Andric break;
36775ffd83dbSDimitry Andric case BO_DivAssign:
3678af732203SDimitry Andric case BO_Div:
3679af732203SDimitry Andric Result = FPBuilder.CreateDiv(LHS, LHSFixedSema, RHS, RHSFixedSema);
36805ffd83dbSDimitry Andric break;
3681af732203SDimitry Andric case BO_ShlAssign:
3682af732203SDimitry Andric case BO_Shl:
3683af732203SDimitry Andric Result = FPBuilder.CreateShl(LHS, LHSFixedSema, RHS);
3684af732203SDimitry Andric break;
3685af732203SDimitry Andric case BO_ShrAssign:
3686af732203SDimitry Andric case BO_Shr:
3687af732203SDimitry Andric Result = FPBuilder.CreateShr(LHS, LHSFixedSema, RHS);
3688af732203SDimitry Andric break;
36890b57cec5SDimitry Andric case BO_LT:
3690af732203SDimitry Andric return FPBuilder.CreateLT(LHS, LHSFixedSema, RHS, RHSFixedSema);
36910b57cec5SDimitry Andric case BO_GT:
3692af732203SDimitry Andric return FPBuilder.CreateGT(LHS, LHSFixedSema, RHS, RHSFixedSema);
36930b57cec5SDimitry Andric case BO_LE:
3694af732203SDimitry Andric return FPBuilder.CreateLE(LHS, LHSFixedSema, RHS, RHSFixedSema);
36950b57cec5SDimitry Andric case BO_GE:
3696af732203SDimitry Andric return FPBuilder.CreateGE(LHS, LHSFixedSema, RHS, RHSFixedSema);
36970b57cec5SDimitry Andric case BO_EQ:
36980b57cec5SDimitry Andric // For equality operations, we assume any padding bits on unsigned types are
36990b57cec5SDimitry Andric // zero'd out. They could be overwritten through non-saturating operations
37000b57cec5SDimitry Andric // that cause overflow, but this leads to undefined behavior.
3701af732203SDimitry Andric return FPBuilder.CreateEQ(LHS, LHSFixedSema, RHS, RHSFixedSema);
37020b57cec5SDimitry Andric case BO_NE:
3703af732203SDimitry Andric return FPBuilder.CreateNE(LHS, LHSFixedSema, RHS, RHSFixedSema);
37040b57cec5SDimitry Andric case BO_Cmp:
37050b57cec5SDimitry Andric case BO_LAnd:
37060b57cec5SDimitry Andric case BO_LOr:
37070b57cec5SDimitry Andric llvm_unreachable("Found unimplemented fixed point binary operation");
37080b57cec5SDimitry Andric case BO_PtrMemD:
37090b57cec5SDimitry Andric case BO_PtrMemI:
37100b57cec5SDimitry Andric case BO_Rem:
37110b57cec5SDimitry Andric case BO_Xor:
37120b57cec5SDimitry Andric case BO_And:
37130b57cec5SDimitry Andric case BO_Or:
37140b57cec5SDimitry Andric case BO_Assign:
37150b57cec5SDimitry Andric case BO_RemAssign:
37160b57cec5SDimitry Andric case BO_AndAssign:
37170b57cec5SDimitry Andric case BO_XorAssign:
37180b57cec5SDimitry Andric case BO_OrAssign:
37190b57cec5SDimitry Andric case BO_Comma:
37200b57cec5SDimitry Andric llvm_unreachable("Found unsupported binary operation for fixed point types.");
37210b57cec5SDimitry Andric }
37220b57cec5SDimitry Andric
3723af732203SDimitry Andric bool IsShift = BinaryOperator::isShiftOp(op.Opcode) ||
3724af732203SDimitry Andric BinaryOperator::isShiftAssignOp(op.Opcode);
37250b57cec5SDimitry Andric // Convert to the result type.
3726af732203SDimitry Andric return FPBuilder.CreateFixedToFixed(Result, IsShift ? LHSFixedSema
3727af732203SDimitry Andric : CommonFixedSema,
3728af732203SDimitry Andric ResultFixedSema);
37290b57cec5SDimitry Andric }
37300b57cec5SDimitry Andric
EmitSub(const BinOpInfo & op)37310b57cec5SDimitry Andric Value *ScalarExprEmitter::EmitSub(const BinOpInfo &op) {
37320b57cec5SDimitry Andric // The LHS is always a pointer if either side is.
37330b57cec5SDimitry Andric if (!op.LHS->getType()->isPointerTy()) {
37340b57cec5SDimitry Andric if (op.Ty->isSignedIntegerOrEnumerationType()) {
37350b57cec5SDimitry Andric switch (CGF.getLangOpts().getSignedOverflowBehavior()) {
37360b57cec5SDimitry Andric case LangOptions::SOB_Defined:
37370b57cec5SDimitry Andric return Builder.CreateSub(op.LHS, op.RHS, "sub");
37380b57cec5SDimitry Andric case LangOptions::SOB_Undefined:
37390b57cec5SDimitry Andric if (!CGF.SanOpts.has(SanitizerKind::SignedIntegerOverflow))
37400b57cec5SDimitry Andric return Builder.CreateNSWSub(op.LHS, op.RHS, "sub");
37410b57cec5SDimitry Andric LLVM_FALLTHROUGH;
37420b57cec5SDimitry Andric case LangOptions::SOB_Trapping:
37430b57cec5SDimitry Andric if (CanElideOverflowCheck(CGF.getContext(), op))
37440b57cec5SDimitry Andric return Builder.CreateNSWSub(op.LHS, op.RHS, "sub");
37450b57cec5SDimitry Andric return EmitOverflowCheckedBinOp(op);
37460b57cec5SDimitry Andric }
37470b57cec5SDimitry Andric }
37480b57cec5SDimitry Andric
37495ffd83dbSDimitry Andric if (op.Ty->isConstantMatrixType()) {
37505ffd83dbSDimitry Andric llvm::MatrixBuilder<CGBuilderTy> MB(Builder);
3751*5f7ddb14SDimitry Andric CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, op.FPFeatures);
37525ffd83dbSDimitry Andric return MB.CreateSub(op.LHS, op.RHS);
37535ffd83dbSDimitry Andric }
37545ffd83dbSDimitry Andric
37550b57cec5SDimitry Andric if (op.Ty->isUnsignedIntegerType() &&
37560b57cec5SDimitry Andric CGF.SanOpts.has(SanitizerKind::UnsignedIntegerOverflow) &&
37570b57cec5SDimitry Andric !CanElideOverflowCheck(CGF.getContext(), op))
37580b57cec5SDimitry Andric return EmitOverflowCheckedBinOp(op);
37590b57cec5SDimitry Andric
37600b57cec5SDimitry Andric if (op.LHS->getType()->isFPOrFPVectorTy()) {
37615ffd83dbSDimitry Andric CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, op.FPFeatures);
37620b57cec5SDimitry Andric // Try to form an fmuladd.
37630b57cec5SDimitry Andric if (Value *FMulAdd = tryEmitFMulAdd(op, CGF, Builder, true))
37640b57cec5SDimitry Andric return FMulAdd;
37655ffd83dbSDimitry Andric return Builder.CreateFSub(op.LHS, op.RHS, "sub");
37660b57cec5SDimitry Andric }
37670b57cec5SDimitry Andric
37685ffd83dbSDimitry Andric if (op.isFixedPointOp())
37690b57cec5SDimitry Andric return EmitFixedPointBinOp(op);
37700b57cec5SDimitry Andric
37710b57cec5SDimitry Andric return Builder.CreateSub(op.LHS, op.RHS, "sub");
37720b57cec5SDimitry Andric }
37730b57cec5SDimitry Andric
37740b57cec5SDimitry Andric // If the RHS is not a pointer, then we have normal pointer
37750b57cec5SDimitry Andric // arithmetic.
37760b57cec5SDimitry Andric if (!op.RHS->getType()->isPointerTy())
37770b57cec5SDimitry Andric return emitPointerArithmetic(CGF, op, CodeGenFunction::IsSubtraction);
37780b57cec5SDimitry Andric
37790b57cec5SDimitry Andric // Otherwise, this is a pointer subtraction.
37800b57cec5SDimitry Andric
37810b57cec5SDimitry Andric // Do the raw subtraction part.
37820b57cec5SDimitry Andric llvm::Value *LHS
37830b57cec5SDimitry Andric = Builder.CreatePtrToInt(op.LHS, CGF.PtrDiffTy, "sub.ptr.lhs.cast");
37840b57cec5SDimitry Andric llvm::Value *RHS
37850b57cec5SDimitry Andric = Builder.CreatePtrToInt(op.RHS, CGF.PtrDiffTy, "sub.ptr.rhs.cast");
37860b57cec5SDimitry Andric Value *diffInChars = Builder.CreateSub(LHS, RHS, "sub.ptr.sub");
37870b57cec5SDimitry Andric
37880b57cec5SDimitry Andric // Okay, figure out the element size.
37890b57cec5SDimitry Andric const BinaryOperator *expr = cast<BinaryOperator>(op.E);
37900b57cec5SDimitry Andric QualType elementType = expr->getLHS()->getType()->getPointeeType();
37910b57cec5SDimitry Andric
37920b57cec5SDimitry Andric llvm::Value *divisor = nullptr;
37930b57cec5SDimitry Andric
37940b57cec5SDimitry Andric // For a variable-length array, this is going to be non-constant.
37950b57cec5SDimitry Andric if (const VariableArrayType *vla
37960b57cec5SDimitry Andric = CGF.getContext().getAsVariableArrayType(elementType)) {
37970b57cec5SDimitry Andric auto VlaSize = CGF.getVLASize(vla);
37980b57cec5SDimitry Andric elementType = VlaSize.Type;
37990b57cec5SDimitry Andric divisor = VlaSize.NumElts;
38000b57cec5SDimitry Andric
38010b57cec5SDimitry Andric // Scale the number of non-VLA elements by the non-VLA element size.
38020b57cec5SDimitry Andric CharUnits eltSize = CGF.getContext().getTypeSizeInChars(elementType);
38030b57cec5SDimitry Andric if (!eltSize.isOne())
38040b57cec5SDimitry Andric divisor = CGF.Builder.CreateNUWMul(CGF.CGM.getSize(eltSize), divisor);
38050b57cec5SDimitry Andric
38060b57cec5SDimitry Andric // For everything elese, we can just compute it, safe in the
38070b57cec5SDimitry Andric // assumption that Sema won't let anything through that we can't
38080b57cec5SDimitry Andric // safely compute the size of.
38090b57cec5SDimitry Andric } else {
38100b57cec5SDimitry Andric CharUnits elementSize;
38110b57cec5SDimitry Andric // Handle GCC extension for pointer arithmetic on void* and
38120b57cec5SDimitry Andric // function pointer types.
38130b57cec5SDimitry Andric if (elementType->isVoidType() || elementType->isFunctionType())
38140b57cec5SDimitry Andric elementSize = CharUnits::One();
38150b57cec5SDimitry Andric else
38160b57cec5SDimitry Andric elementSize = CGF.getContext().getTypeSizeInChars(elementType);
38170b57cec5SDimitry Andric
38180b57cec5SDimitry Andric // Don't even emit the divide for element size of 1.
38190b57cec5SDimitry Andric if (elementSize.isOne())
38200b57cec5SDimitry Andric return diffInChars;
38210b57cec5SDimitry Andric
38220b57cec5SDimitry Andric divisor = CGF.CGM.getSize(elementSize);
38230b57cec5SDimitry Andric }
38240b57cec5SDimitry Andric
38250b57cec5SDimitry Andric // Otherwise, do a full sdiv. This uses the "exact" form of sdiv, since
38260b57cec5SDimitry Andric // pointer difference in C is only defined in the case where both operands
38270b57cec5SDimitry Andric // are pointing to elements of an array.
38280b57cec5SDimitry Andric return Builder.CreateExactSDiv(diffInChars, divisor, "sub.ptr.div");
38290b57cec5SDimitry Andric }
38300b57cec5SDimitry Andric
GetWidthMinusOneValue(Value * LHS,Value * RHS)38310b57cec5SDimitry Andric Value *ScalarExprEmitter::GetWidthMinusOneValue(Value* LHS,Value* RHS) {
38320b57cec5SDimitry Andric llvm::IntegerType *Ty;
38330b57cec5SDimitry Andric if (llvm::VectorType *VT = dyn_cast<llvm::VectorType>(LHS->getType()))
38340b57cec5SDimitry Andric Ty = cast<llvm::IntegerType>(VT->getElementType());
38350b57cec5SDimitry Andric else
38360b57cec5SDimitry Andric Ty = cast<llvm::IntegerType>(LHS->getType());
38370b57cec5SDimitry Andric return llvm::ConstantInt::get(RHS->getType(), Ty->getBitWidth() - 1);
38380b57cec5SDimitry Andric }
38390b57cec5SDimitry Andric
ConstrainShiftValue(Value * LHS,Value * RHS,const Twine & Name)38405ffd83dbSDimitry Andric Value *ScalarExprEmitter::ConstrainShiftValue(Value *LHS, Value *RHS,
38415ffd83dbSDimitry Andric const Twine &Name) {
38425ffd83dbSDimitry Andric llvm::IntegerType *Ty;
38435ffd83dbSDimitry Andric if (auto *VT = dyn_cast<llvm::VectorType>(LHS->getType()))
38445ffd83dbSDimitry Andric Ty = cast<llvm::IntegerType>(VT->getElementType());
38455ffd83dbSDimitry Andric else
38465ffd83dbSDimitry Andric Ty = cast<llvm::IntegerType>(LHS->getType());
38475ffd83dbSDimitry Andric
38485ffd83dbSDimitry Andric if (llvm::isPowerOf2_64(Ty->getBitWidth()))
38495ffd83dbSDimitry Andric return Builder.CreateAnd(RHS, GetWidthMinusOneValue(LHS, RHS), Name);
38505ffd83dbSDimitry Andric
38515ffd83dbSDimitry Andric return Builder.CreateURem(
38525ffd83dbSDimitry Andric RHS, llvm::ConstantInt::get(RHS->getType(), Ty->getBitWidth()), Name);
38535ffd83dbSDimitry Andric }
38545ffd83dbSDimitry Andric
EmitShl(const BinOpInfo & Ops)38550b57cec5SDimitry Andric Value *ScalarExprEmitter::EmitShl(const BinOpInfo &Ops) {
3856af732203SDimitry Andric // TODO: This misses out on the sanitizer check below.
3857af732203SDimitry Andric if (Ops.isFixedPointOp())
3858af732203SDimitry Andric return EmitFixedPointBinOp(Ops);
3859af732203SDimitry Andric
38600b57cec5SDimitry Andric // LLVM requires the LHS and RHS to be the same type: promote or truncate the
38610b57cec5SDimitry Andric // RHS to the same size as the LHS.
38620b57cec5SDimitry Andric Value *RHS = Ops.RHS;
38630b57cec5SDimitry Andric if (Ops.LHS->getType() != RHS->getType())
38640b57cec5SDimitry Andric RHS = Builder.CreateIntCast(RHS, Ops.LHS->getType(), false, "sh_prom");
38650b57cec5SDimitry Andric
3866af732203SDimitry Andric bool SanitizeSignedBase = CGF.SanOpts.has(SanitizerKind::ShiftBase) &&
38670b57cec5SDimitry Andric Ops.Ty->hasSignedIntegerRepresentation() &&
38680b57cec5SDimitry Andric !CGF.getLangOpts().isSignedOverflowDefined() &&
38695ffd83dbSDimitry Andric !CGF.getLangOpts().CPlusPlus20;
3870af732203SDimitry Andric bool SanitizeUnsignedBase =
3871af732203SDimitry Andric CGF.SanOpts.has(SanitizerKind::UnsignedShiftBase) &&
3872af732203SDimitry Andric Ops.Ty->hasUnsignedIntegerRepresentation();
3873af732203SDimitry Andric bool SanitizeBase = SanitizeSignedBase || SanitizeUnsignedBase;
38740b57cec5SDimitry Andric bool SanitizeExponent = CGF.SanOpts.has(SanitizerKind::ShiftExponent);
38750b57cec5SDimitry Andric // OpenCL 6.3j: shift values are effectively % word size of LHS.
38760b57cec5SDimitry Andric if (CGF.getLangOpts().OpenCL)
38775ffd83dbSDimitry Andric RHS = ConstrainShiftValue(Ops.LHS, RHS, "shl.mask");
38780b57cec5SDimitry Andric else if ((SanitizeBase || SanitizeExponent) &&
38790b57cec5SDimitry Andric isa<llvm::IntegerType>(Ops.LHS->getType())) {
38800b57cec5SDimitry Andric CodeGenFunction::SanitizerScope SanScope(&CGF);
38810b57cec5SDimitry Andric SmallVector<std::pair<Value *, SanitizerMask>, 2> Checks;
38820b57cec5SDimitry Andric llvm::Value *WidthMinusOne = GetWidthMinusOneValue(Ops.LHS, Ops.RHS);
38830b57cec5SDimitry Andric llvm::Value *ValidExponent = Builder.CreateICmpULE(Ops.RHS, WidthMinusOne);
38840b57cec5SDimitry Andric
38850b57cec5SDimitry Andric if (SanitizeExponent) {
38860b57cec5SDimitry Andric Checks.push_back(
38870b57cec5SDimitry Andric std::make_pair(ValidExponent, SanitizerKind::ShiftExponent));
38880b57cec5SDimitry Andric }
38890b57cec5SDimitry Andric
38900b57cec5SDimitry Andric if (SanitizeBase) {
38910b57cec5SDimitry Andric // Check whether we are shifting any non-zero bits off the top of the
38920b57cec5SDimitry Andric // integer. We only emit this check if exponent is valid - otherwise
38930b57cec5SDimitry Andric // instructions below will have undefined behavior themselves.
38940b57cec5SDimitry Andric llvm::BasicBlock *Orig = Builder.GetInsertBlock();
38950b57cec5SDimitry Andric llvm::BasicBlock *Cont = CGF.createBasicBlock("cont");
38960b57cec5SDimitry Andric llvm::BasicBlock *CheckShiftBase = CGF.createBasicBlock("check");
38970b57cec5SDimitry Andric Builder.CreateCondBr(ValidExponent, CheckShiftBase, Cont);
38980b57cec5SDimitry Andric llvm::Value *PromotedWidthMinusOne =
38990b57cec5SDimitry Andric (RHS == Ops.RHS) ? WidthMinusOne
39000b57cec5SDimitry Andric : GetWidthMinusOneValue(Ops.LHS, RHS);
39010b57cec5SDimitry Andric CGF.EmitBlock(CheckShiftBase);
39020b57cec5SDimitry Andric llvm::Value *BitsShiftedOff = Builder.CreateLShr(
39030b57cec5SDimitry Andric Ops.LHS, Builder.CreateSub(PromotedWidthMinusOne, RHS, "shl.zeros",
39040b57cec5SDimitry Andric /*NUW*/ true, /*NSW*/ true),
39050b57cec5SDimitry Andric "shl.check");
3906af732203SDimitry Andric if (SanitizeUnsignedBase || CGF.getLangOpts().CPlusPlus) {
39070b57cec5SDimitry Andric // In C99, we are not permitted to shift a 1 bit into the sign bit.
39080b57cec5SDimitry Andric // Under C++11's rules, shifting a 1 bit into the sign bit is
39090b57cec5SDimitry Andric // OK, but shifting a 1 bit out of it is not. (C89 and C++03 don't
39100b57cec5SDimitry Andric // define signed left shifts, so we use the C99 and C++11 rules there).
3911af732203SDimitry Andric // Unsigned shifts can always shift into the top bit.
39120b57cec5SDimitry Andric llvm::Value *One = llvm::ConstantInt::get(BitsShiftedOff->getType(), 1);
39130b57cec5SDimitry Andric BitsShiftedOff = Builder.CreateLShr(BitsShiftedOff, One);
39140b57cec5SDimitry Andric }
39150b57cec5SDimitry Andric llvm::Value *Zero = llvm::ConstantInt::get(BitsShiftedOff->getType(), 0);
39160b57cec5SDimitry Andric llvm::Value *ValidBase = Builder.CreateICmpEQ(BitsShiftedOff, Zero);
39170b57cec5SDimitry Andric CGF.EmitBlock(Cont);
39180b57cec5SDimitry Andric llvm::PHINode *BaseCheck = Builder.CreatePHI(ValidBase->getType(), 2);
39190b57cec5SDimitry Andric BaseCheck->addIncoming(Builder.getTrue(), Orig);
39200b57cec5SDimitry Andric BaseCheck->addIncoming(ValidBase, CheckShiftBase);
3921af732203SDimitry Andric Checks.push_back(std::make_pair(
3922af732203SDimitry Andric BaseCheck, SanitizeSignedBase ? SanitizerKind::ShiftBase
3923af732203SDimitry Andric : SanitizerKind::UnsignedShiftBase));
39240b57cec5SDimitry Andric }
39250b57cec5SDimitry Andric
39260b57cec5SDimitry Andric assert(!Checks.empty());
39270b57cec5SDimitry Andric EmitBinOpCheck(Checks, Ops);
39280b57cec5SDimitry Andric }
39290b57cec5SDimitry Andric
39300b57cec5SDimitry Andric return Builder.CreateShl(Ops.LHS, RHS, "shl");
39310b57cec5SDimitry Andric }
39320b57cec5SDimitry Andric
EmitShr(const BinOpInfo & Ops)39330b57cec5SDimitry Andric Value *ScalarExprEmitter::EmitShr(const BinOpInfo &Ops) {
3934af732203SDimitry Andric // TODO: This misses out on the sanitizer check below.
3935af732203SDimitry Andric if (Ops.isFixedPointOp())
3936af732203SDimitry Andric return EmitFixedPointBinOp(Ops);
3937af732203SDimitry Andric
39380b57cec5SDimitry Andric // LLVM requires the LHS and RHS to be the same type: promote or truncate the
39390b57cec5SDimitry Andric // RHS to the same size as the LHS.
39400b57cec5SDimitry Andric Value *RHS = Ops.RHS;
39410b57cec5SDimitry Andric if (Ops.LHS->getType() != RHS->getType())
39420b57cec5SDimitry Andric RHS = Builder.CreateIntCast(RHS, Ops.LHS->getType(), false, "sh_prom");
39430b57cec5SDimitry Andric
39440b57cec5SDimitry Andric // OpenCL 6.3j: shift values are effectively % word size of LHS.
39450b57cec5SDimitry Andric if (CGF.getLangOpts().OpenCL)
39465ffd83dbSDimitry Andric RHS = ConstrainShiftValue(Ops.LHS, RHS, "shr.mask");
39470b57cec5SDimitry Andric else if (CGF.SanOpts.has(SanitizerKind::ShiftExponent) &&
39480b57cec5SDimitry Andric isa<llvm::IntegerType>(Ops.LHS->getType())) {
39490b57cec5SDimitry Andric CodeGenFunction::SanitizerScope SanScope(&CGF);
39500b57cec5SDimitry Andric llvm::Value *Valid =
39510b57cec5SDimitry Andric Builder.CreateICmpULE(RHS, GetWidthMinusOneValue(Ops.LHS, RHS));
39520b57cec5SDimitry Andric EmitBinOpCheck(std::make_pair(Valid, SanitizerKind::ShiftExponent), Ops);
39530b57cec5SDimitry Andric }
39540b57cec5SDimitry Andric
39550b57cec5SDimitry Andric if (Ops.Ty->hasUnsignedIntegerRepresentation())
39560b57cec5SDimitry Andric return Builder.CreateLShr(Ops.LHS, RHS, "shr");
39570b57cec5SDimitry Andric return Builder.CreateAShr(Ops.LHS, RHS, "shr");
39580b57cec5SDimitry Andric }
39590b57cec5SDimitry Andric
39600b57cec5SDimitry Andric enum IntrinsicType { VCMPEQ, VCMPGT };
39610b57cec5SDimitry Andric // return corresponding comparison intrinsic for given vector type
GetIntrinsic(IntrinsicType IT,BuiltinType::Kind ElemKind)39620b57cec5SDimitry Andric static llvm::Intrinsic::ID GetIntrinsic(IntrinsicType IT,
39630b57cec5SDimitry Andric BuiltinType::Kind ElemKind) {
39640b57cec5SDimitry Andric switch (ElemKind) {
39650b57cec5SDimitry Andric default: llvm_unreachable("unexpected element type");
39660b57cec5SDimitry Andric case BuiltinType::Char_U:
39670b57cec5SDimitry Andric case BuiltinType::UChar:
39680b57cec5SDimitry Andric return (IT == VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequb_p :
39690b57cec5SDimitry Andric llvm::Intrinsic::ppc_altivec_vcmpgtub_p;
39700b57cec5SDimitry Andric case BuiltinType::Char_S:
39710b57cec5SDimitry Andric case BuiltinType::SChar:
39720b57cec5SDimitry Andric return (IT == VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequb_p :
39730b57cec5SDimitry Andric llvm::Intrinsic::ppc_altivec_vcmpgtsb_p;
39740b57cec5SDimitry Andric case BuiltinType::UShort:
39750b57cec5SDimitry Andric return (IT == VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequh_p :
39760b57cec5SDimitry Andric llvm::Intrinsic::ppc_altivec_vcmpgtuh_p;
39770b57cec5SDimitry Andric case BuiltinType::Short:
39780b57cec5SDimitry Andric return (IT == VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequh_p :
39790b57cec5SDimitry Andric llvm::Intrinsic::ppc_altivec_vcmpgtsh_p;
39800b57cec5SDimitry Andric case BuiltinType::UInt:
39810b57cec5SDimitry Andric return (IT == VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequw_p :
39820b57cec5SDimitry Andric llvm::Intrinsic::ppc_altivec_vcmpgtuw_p;
39830b57cec5SDimitry Andric case BuiltinType::Int:
39840b57cec5SDimitry Andric return (IT == VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequw_p :
39850b57cec5SDimitry Andric llvm::Intrinsic::ppc_altivec_vcmpgtsw_p;
39860b57cec5SDimitry Andric case BuiltinType::ULong:
39870b57cec5SDimitry Andric case BuiltinType::ULongLong:
39880b57cec5SDimitry Andric return (IT == VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequd_p :
39890b57cec5SDimitry Andric llvm::Intrinsic::ppc_altivec_vcmpgtud_p;
39900b57cec5SDimitry Andric case BuiltinType::Long:
39910b57cec5SDimitry Andric case BuiltinType::LongLong:
39920b57cec5SDimitry Andric return (IT == VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequd_p :
39930b57cec5SDimitry Andric llvm::Intrinsic::ppc_altivec_vcmpgtsd_p;
39940b57cec5SDimitry Andric case BuiltinType::Float:
39950b57cec5SDimitry Andric return (IT == VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpeqfp_p :
39960b57cec5SDimitry Andric llvm::Intrinsic::ppc_altivec_vcmpgtfp_p;
39970b57cec5SDimitry Andric case BuiltinType::Double:
39980b57cec5SDimitry Andric return (IT == VCMPEQ) ? llvm::Intrinsic::ppc_vsx_xvcmpeqdp_p :
39990b57cec5SDimitry Andric llvm::Intrinsic::ppc_vsx_xvcmpgtdp_p;
4000af732203SDimitry Andric case BuiltinType::UInt128:
4001af732203SDimitry Andric return (IT == VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequq_p
4002af732203SDimitry Andric : llvm::Intrinsic::ppc_altivec_vcmpgtuq_p;
4003af732203SDimitry Andric case BuiltinType::Int128:
4004af732203SDimitry Andric return (IT == VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequq_p
4005af732203SDimitry Andric : llvm::Intrinsic::ppc_altivec_vcmpgtsq_p;
40060b57cec5SDimitry Andric }
40070b57cec5SDimitry Andric }
40080b57cec5SDimitry Andric
EmitCompare(const BinaryOperator * E,llvm::CmpInst::Predicate UICmpOpc,llvm::CmpInst::Predicate SICmpOpc,llvm::CmpInst::Predicate FCmpOpc,bool IsSignaling)40090b57cec5SDimitry Andric Value *ScalarExprEmitter::EmitCompare(const BinaryOperator *E,
40100b57cec5SDimitry Andric llvm::CmpInst::Predicate UICmpOpc,
40110b57cec5SDimitry Andric llvm::CmpInst::Predicate SICmpOpc,
4012480093f4SDimitry Andric llvm::CmpInst::Predicate FCmpOpc,
4013480093f4SDimitry Andric bool IsSignaling) {
40140b57cec5SDimitry Andric TestAndClearIgnoreResultAssign();
40150b57cec5SDimitry Andric Value *Result;
40160b57cec5SDimitry Andric QualType LHSTy = E->getLHS()->getType();
40170b57cec5SDimitry Andric QualType RHSTy = E->getRHS()->getType();
40180b57cec5SDimitry Andric if (const MemberPointerType *MPT = LHSTy->getAs<MemberPointerType>()) {
40190b57cec5SDimitry Andric assert(E->getOpcode() == BO_EQ ||
40200b57cec5SDimitry Andric E->getOpcode() == BO_NE);
40210b57cec5SDimitry Andric Value *LHS = CGF.EmitScalarExpr(E->getLHS());
40220b57cec5SDimitry Andric Value *RHS = CGF.EmitScalarExpr(E->getRHS());
40230b57cec5SDimitry Andric Result = CGF.CGM.getCXXABI().EmitMemberPointerComparison(
40240b57cec5SDimitry Andric CGF, LHS, RHS, MPT, E->getOpcode() == BO_NE);
40250b57cec5SDimitry Andric } else if (!LHSTy->isAnyComplexType() && !RHSTy->isAnyComplexType()) {
40260b57cec5SDimitry Andric BinOpInfo BOInfo = EmitBinOps(E);
40270b57cec5SDimitry Andric Value *LHS = BOInfo.LHS;
40280b57cec5SDimitry Andric Value *RHS = BOInfo.RHS;
40290b57cec5SDimitry Andric
40300b57cec5SDimitry Andric // If AltiVec, the comparison results in a numeric type, so we use
40310b57cec5SDimitry Andric // intrinsics comparing vectors and giving 0 or 1 as a result
40320b57cec5SDimitry Andric if (LHSTy->isVectorType() && !E->getType()->isVectorType()) {
40330b57cec5SDimitry Andric // constants for mapping CR6 register bits to predicate result
40340b57cec5SDimitry Andric enum { CR6_EQ=0, CR6_EQ_REV, CR6_LT, CR6_LT_REV } CR6;
40350b57cec5SDimitry Andric
40360b57cec5SDimitry Andric llvm::Intrinsic::ID ID = llvm::Intrinsic::not_intrinsic;
40370b57cec5SDimitry Andric
40380b57cec5SDimitry Andric // in several cases vector arguments order will be reversed
40390b57cec5SDimitry Andric Value *FirstVecArg = LHS,
40400b57cec5SDimitry Andric *SecondVecArg = RHS;
40410b57cec5SDimitry Andric
4042a7dea167SDimitry Andric QualType ElTy = LHSTy->castAs<VectorType>()->getElementType();
4043480093f4SDimitry Andric BuiltinType::Kind ElementKind = ElTy->castAs<BuiltinType>()->getKind();
40440b57cec5SDimitry Andric
40450b57cec5SDimitry Andric switch(E->getOpcode()) {
40460b57cec5SDimitry Andric default: llvm_unreachable("is not a comparison operation");
40470b57cec5SDimitry Andric case BO_EQ:
40480b57cec5SDimitry Andric CR6 = CR6_LT;
40490b57cec5SDimitry Andric ID = GetIntrinsic(VCMPEQ, ElementKind);
40500b57cec5SDimitry Andric break;
40510b57cec5SDimitry Andric case BO_NE:
40520b57cec5SDimitry Andric CR6 = CR6_EQ;
40530b57cec5SDimitry Andric ID = GetIntrinsic(VCMPEQ, ElementKind);
40540b57cec5SDimitry Andric break;
40550b57cec5SDimitry Andric case BO_LT:
40560b57cec5SDimitry Andric CR6 = CR6_LT;
40570b57cec5SDimitry Andric ID = GetIntrinsic(VCMPGT, ElementKind);
40580b57cec5SDimitry Andric std::swap(FirstVecArg, SecondVecArg);
40590b57cec5SDimitry Andric break;
40600b57cec5SDimitry Andric case BO_GT:
40610b57cec5SDimitry Andric CR6 = CR6_LT;
40620b57cec5SDimitry Andric ID = GetIntrinsic(VCMPGT, ElementKind);
40630b57cec5SDimitry Andric break;
40640b57cec5SDimitry Andric case BO_LE:
40650b57cec5SDimitry Andric if (ElementKind == BuiltinType::Float) {
40660b57cec5SDimitry Andric CR6 = CR6_LT;
40670b57cec5SDimitry Andric ID = llvm::Intrinsic::ppc_altivec_vcmpgefp_p;
40680b57cec5SDimitry Andric std::swap(FirstVecArg, SecondVecArg);
40690b57cec5SDimitry Andric }
40700b57cec5SDimitry Andric else {
40710b57cec5SDimitry Andric CR6 = CR6_EQ;
40720b57cec5SDimitry Andric ID = GetIntrinsic(VCMPGT, ElementKind);
40730b57cec5SDimitry Andric }
40740b57cec5SDimitry Andric break;
40750b57cec5SDimitry Andric case BO_GE:
40760b57cec5SDimitry Andric if (ElementKind == BuiltinType::Float) {
40770b57cec5SDimitry Andric CR6 = CR6_LT;
40780b57cec5SDimitry Andric ID = llvm::Intrinsic::ppc_altivec_vcmpgefp_p;
40790b57cec5SDimitry Andric }
40800b57cec5SDimitry Andric else {
40810b57cec5SDimitry Andric CR6 = CR6_EQ;
40820b57cec5SDimitry Andric ID = GetIntrinsic(VCMPGT, ElementKind);
40830b57cec5SDimitry Andric std::swap(FirstVecArg, SecondVecArg);
40840b57cec5SDimitry Andric }
40850b57cec5SDimitry Andric break;
40860b57cec5SDimitry Andric }
40870b57cec5SDimitry Andric
40880b57cec5SDimitry Andric Value *CR6Param = Builder.getInt32(CR6);
40890b57cec5SDimitry Andric llvm::Function *F = CGF.CGM.getIntrinsic(ID);
40900b57cec5SDimitry Andric Result = Builder.CreateCall(F, {CR6Param, FirstVecArg, SecondVecArg});
40910b57cec5SDimitry Andric
40920b57cec5SDimitry Andric // The result type of intrinsic may not be same as E->getType().
40930b57cec5SDimitry Andric // If E->getType() is not BoolTy, EmitScalarConversion will do the
40940b57cec5SDimitry Andric // conversion work. If E->getType() is BoolTy, EmitScalarConversion will
40950b57cec5SDimitry Andric // do nothing, if ResultTy is not i1 at the same time, it will cause
40960b57cec5SDimitry Andric // crash later.
40970b57cec5SDimitry Andric llvm::IntegerType *ResultTy = cast<llvm::IntegerType>(Result->getType());
40980b57cec5SDimitry Andric if (ResultTy->getBitWidth() > 1 &&
40990b57cec5SDimitry Andric E->getType() == CGF.getContext().BoolTy)
41000b57cec5SDimitry Andric Result = Builder.CreateTrunc(Result, Builder.getInt1Ty());
41010b57cec5SDimitry Andric return EmitScalarConversion(Result, CGF.getContext().BoolTy, E->getType(),
41020b57cec5SDimitry Andric E->getExprLoc());
41030b57cec5SDimitry Andric }
41040b57cec5SDimitry Andric
41055ffd83dbSDimitry Andric if (BOInfo.isFixedPointOp()) {
41060b57cec5SDimitry Andric Result = EmitFixedPointBinOp(BOInfo);
41070b57cec5SDimitry Andric } else if (LHS->getType()->isFPOrFPVectorTy()) {
41085ffd83dbSDimitry Andric CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, BOInfo.FPFeatures);
4109480093f4SDimitry Andric if (!IsSignaling)
41100b57cec5SDimitry Andric Result = Builder.CreateFCmp(FCmpOpc, LHS, RHS, "cmp");
4111480093f4SDimitry Andric else
4112480093f4SDimitry Andric Result = Builder.CreateFCmpS(FCmpOpc, LHS, RHS, "cmp");
41130b57cec5SDimitry Andric } else if (LHSTy->hasSignedIntegerRepresentation()) {
41140b57cec5SDimitry Andric Result = Builder.CreateICmp(SICmpOpc, LHS, RHS, "cmp");
41150b57cec5SDimitry Andric } else {
41160b57cec5SDimitry Andric // Unsigned integers and pointers.
41170b57cec5SDimitry Andric
41180b57cec5SDimitry Andric if (CGF.CGM.getCodeGenOpts().StrictVTablePointers &&
41190b57cec5SDimitry Andric !isa<llvm::ConstantPointerNull>(LHS) &&
41200b57cec5SDimitry Andric !isa<llvm::ConstantPointerNull>(RHS)) {
41210b57cec5SDimitry Andric
41220b57cec5SDimitry Andric // Dynamic information is required to be stripped for comparisons,
41230b57cec5SDimitry Andric // because it could leak the dynamic information. Based on comparisons
41240b57cec5SDimitry Andric // of pointers to dynamic objects, the optimizer can replace one pointer
41250b57cec5SDimitry Andric // with another, which might be incorrect in presence of invariant
41260b57cec5SDimitry Andric // groups. Comparison with null is safe because null does not carry any
41270b57cec5SDimitry Andric // dynamic information.
41280b57cec5SDimitry Andric if (LHSTy.mayBeDynamicClass())
41290b57cec5SDimitry Andric LHS = Builder.CreateStripInvariantGroup(LHS);
41300b57cec5SDimitry Andric if (RHSTy.mayBeDynamicClass())
41310b57cec5SDimitry Andric RHS = Builder.CreateStripInvariantGroup(RHS);
41320b57cec5SDimitry Andric }
41330b57cec5SDimitry Andric
41340b57cec5SDimitry Andric Result = Builder.CreateICmp(UICmpOpc, LHS, RHS, "cmp");
41350b57cec5SDimitry Andric }
41360b57cec5SDimitry Andric
41370b57cec5SDimitry Andric // If this is a vector comparison, sign extend the result to the appropriate
41380b57cec5SDimitry Andric // vector integer type and return it (don't convert to bool).
41390b57cec5SDimitry Andric if (LHSTy->isVectorType())
41400b57cec5SDimitry Andric return Builder.CreateSExt(Result, ConvertType(E->getType()), "sext");
41410b57cec5SDimitry Andric
41420b57cec5SDimitry Andric } else {
41430b57cec5SDimitry Andric // Complex Comparison: can only be an equality comparison.
41440b57cec5SDimitry Andric CodeGenFunction::ComplexPairTy LHS, RHS;
41450b57cec5SDimitry Andric QualType CETy;
41460b57cec5SDimitry Andric if (auto *CTy = LHSTy->getAs<ComplexType>()) {
41470b57cec5SDimitry Andric LHS = CGF.EmitComplexExpr(E->getLHS());
41480b57cec5SDimitry Andric CETy = CTy->getElementType();
41490b57cec5SDimitry Andric } else {
41500b57cec5SDimitry Andric LHS.first = Visit(E->getLHS());
41510b57cec5SDimitry Andric LHS.second = llvm::Constant::getNullValue(LHS.first->getType());
41520b57cec5SDimitry Andric CETy = LHSTy;
41530b57cec5SDimitry Andric }
41540b57cec5SDimitry Andric if (auto *CTy = RHSTy->getAs<ComplexType>()) {
41550b57cec5SDimitry Andric RHS = CGF.EmitComplexExpr(E->getRHS());
41560b57cec5SDimitry Andric assert(CGF.getContext().hasSameUnqualifiedType(CETy,
41570b57cec5SDimitry Andric CTy->getElementType()) &&
41580b57cec5SDimitry Andric "The element types must always match.");
41590b57cec5SDimitry Andric (void)CTy;
41600b57cec5SDimitry Andric } else {
41610b57cec5SDimitry Andric RHS.first = Visit(E->getRHS());
41620b57cec5SDimitry Andric RHS.second = llvm::Constant::getNullValue(RHS.first->getType());
41630b57cec5SDimitry Andric assert(CGF.getContext().hasSameUnqualifiedType(CETy, RHSTy) &&
41640b57cec5SDimitry Andric "The element types must always match.");
41650b57cec5SDimitry Andric }
41660b57cec5SDimitry Andric
41670b57cec5SDimitry Andric Value *ResultR, *ResultI;
41680b57cec5SDimitry Andric if (CETy->isRealFloatingType()) {
4169480093f4SDimitry Andric // As complex comparisons can only be equality comparisons, they
4170480093f4SDimitry Andric // are never signaling comparisons.
41710b57cec5SDimitry Andric ResultR = Builder.CreateFCmp(FCmpOpc, LHS.first, RHS.first, "cmp.r");
41720b57cec5SDimitry Andric ResultI = Builder.CreateFCmp(FCmpOpc, LHS.second, RHS.second, "cmp.i");
41730b57cec5SDimitry Andric } else {
41740b57cec5SDimitry Andric // Complex comparisons can only be equality comparisons. As such, signed
41750b57cec5SDimitry Andric // and unsigned opcodes are the same.
41760b57cec5SDimitry Andric ResultR = Builder.CreateICmp(UICmpOpc, LHS.first, RHS.first, "cmp.r");
41770b57cec5SDimitry Andric ResultI = Builder.CreateICmp(UICmpOpc, LHS.second, RHS.second, "cmp.i");
41780b57cec5SDimitry Andric }
41790b57cec5SDimitry Andric
41800b57cec5SDimitry Andric if (E->getOpcode() == BO_EQ) {
41810b57cec5SDimitry Andric Result = Builder.CreateAnd(ResultR, ResultI, "and.ri");
41820b57cec5SDimitry Andric } else {
41830b57cec5SDimitry Andric assert(E->getOpcode() == BO_NE &&
41840b57cec5SDimitry Andric "Complex comparison other than == or != ?");
41850b57cec5SDimitry Andric Result = Builder.CreateOr(ResultR, ResultI, "or.ri");
41860b57cec5SDimitry Andric }
41870b57cec5SDimitry Andric }
41880b57cec5SDimitry Andric
41890b57cec5SDimitry Andric return EmitScalarConversion(Result, CGF.getContext().BoolTy, E->getType(),
41900b57cec5SDimitry Andric E->getExprLoc());
41910b57cec5SDimitry Andric }
41920b57cec5SDimitry Andric
VisitBinAssign(const BinaryOperator * E)41930b57cec5SDimitry Andric Value *ScalarExprEmitter::VisitBinAssign(const BinaryOperator *E) {
41940b57cec5SDimitry Andric bool Ignore = TestAndClearIgnoreResultAssign();
41950b57cec5SDimitry Andric
41960b57cec5SDimitry Andric Value *RHS;
41970b57cec5SDimitry Andric LValue LHS;
41980b57cec5SDimitry Andric
41990b57cec5SDimitry Andric switch (E->getLHS()->getType().getObjCLifetime()) {
42000b57cec5SDimitry Andric case Qualifiers::OCL_Strong:
42010b57cec5SDimitry Andric std::tie(LHS, RHS) = CGF.EmitARCStoreStrong(E, Ignore);
42020b57cec5SDimitry Andric break;
42030b57cec5SDimitry Andric
42040b57cec5SDimitry Andric case Qualifiers::OCL_Autoreleasing:
42050b57cec5SDimitry Andric std::tie(LHS, RHS) = CGF.EmitARCStoreAutoreleasing(E);
42060b57cec5SDimitry Andric break;
42070b57cec5SDimitry Andric
42080b57cec5SDimitry Andric case Qualifiers::OCL_ExplicitNone:
42090b57cec5SDimitry Andric std::tie(LHS, RHS) = CGF.EmitARCStoreUnsafeUnretained(E, Ignore);
42100b57cec5SDimitry Andric break;
42110b57cec5SDimitry Andric
42120b57cec5SDimitry Andric case Qualifiers::OCL_Weak:
42130b57cec5SDimitry Andric RHS = Visit(E->getRHS());
42140b57cec5SDimitry Andric LHS = EmitCheckedLValue(E->getLHS(), CodeGenFunction::TCK_Store);
4215480093f4SDimitry Andric RHS = CGF.EmitARCStoreWeak(LHS.getAddress(CGF), RHS, Ignore);
42160b57cec5SDimitry Andric break;
42170b57cec5SDimitry Andric
42180b57cec5SDimitry Andric case Qualifiers::OCL_None:
42190b57cec5SDimitry Andric // __block variables need to have the rhs evaluated first, plus
42200b57cec5SDimitry Andric // this should improve codegen just a little.
42210b57cec5SDimitry Andric RHS = Visit(E->getRHS());
42220b57cec5SDimitry Andric LHS = EmitCheckedLValue(E->getLHS(), CodeGenFunction::TCK_Store);
42230b57cec5SDimitry Andric
42240b57cec5SDimitry Andric // Store the value into the LHS. Bit-fields are handled specially
42250b57cec5SDimitry Andric // because the result is altered by the store, i.e., [C99 6.5.16p1]
42260b57cec5SDimitry Andric // 'An assignment expression has the value of the left operand after
42270b57cec5SDimitry Andric // the assignment...'.
42280b57cec5SDimitry Andric if (LHS.isBitField()) {
42290b57cec5SDimitry Andric CGF.EmitStoreThroughBitfieldLValue(RValue::get(RHS), LHS, &RHS);
42300b57cec5SDimitry Andric } else {
42310b57cec5SDimitry Andric CGF.EmitNullabilityCheck(LHS, RHS, E->getExprLoc());
42320b57cec5SDimitry Andric CGF.EmitStoreThroughLValue(RValue::get(RHS), LHS);
42330b57cec5SDimitry Andric }
42340b57cec5SDimitry Andric }
42350b57cec5SDimitry Andric
42360b57cec5SDimitry Andric // If the result is clearly ignored, return now.
42370b57cec5SDimitry Andric if (Ignore)
42380b57cec5SDimitry Andric return nullptr;
42390b57cec5SDimitry Andric
42400b57cec5SDimitry Andric // The result of an assignment in C is the assigned r-value.
42410b57cec5SDimitry Andric if (!CGF.getLangOpts().CPlusPlus)
42420b57cec5SDimitry Andric return RHS;
42430b57cec5SDimitry Andric
42440b57cec5SDimitry Andric // If the lvalue is non-volatile, return the computed value of the assignment.
42450b57cec5SDimitry Andric if (!LHS.isVolatileQualified())
42460b57cec5SDimitry Andric return RHS;
42470b57cec5SDimitry Andric
42480b57cec5SDimitry Andric // Otherwise, reload the value.
42490b57cec5SDimitry Andric return EmitLoadOfLValue(LHS, E->getExprLoc());
42500b57cec5SDimitry Andric }
42510b57cec5SDimitry Andric
VisitBinLAnd(const BinaryOperator * E)42520b57cec5SDimitry Andric Value *ScalarExprEmitter::VisitBinLAnd(const BinaryOperator *E) {
42530b57cec5SDimitry Andric // Perform vector logical and on comparisons with zero vectors.
42540b57cec5SDimitry Andric if (E->getType()->isVectorType()) {
42550b57cec5SDimitry Andric CGF.incrementProfileCounter(E);
42560b57cec5SDimitry Andric
42570b57cec5SDimitry Andric Value *LHS = Visit(E->getLHS());
42580b57cec5SDimitry Andric Value *RHS = Visit(E->getRHS());
42590b57cec5SDimitry Andric Value *Zero = llvm::ConstantAggregateZero::get(LHS->getType());
42600b57cec5SDimitry Andric if (LHS->getType()->isFPOrFPVectorTy()) {
42615ffd83dbSDimitry Andric CodeGenFunction::CGFPOptionsRAII FPOptsRAII(
42625ffd83dbSDimitry Andric CGF, E->getFPFeaturesInEffect(CGF.getLangOpts()));
42630b57cec5SDimitry Andric LHS = Builder.CreateFCmp(llvm::CmpInst::FCMP_UNE, LHS, Zero, "cmp");
42640b57cec5SDimitry Andric RHS = Builder.CreateFCmp(llvm::CmpInst::FCMP_UNE, RHS, Zero, "cmp");
42650b57cec5SDimitry Andric } else {
42660b57cec5SDimitry Andric LHS = Builder.CreateICmp(llvm::CmpInst::ICMP_NE, LHS, Zero, "cmp");
42670b57cec5SDimitry Andric RHS = Builder.CreateICmp(llvm::CmpInst::ICMP_NE, RHS, Zero, "cmp");
42680b57cec5SDimitry Andric }
42690b57cec5SDimitry Andric Value *And = Builder.CreateAnd(LHS, RHS);
42700b57cec5SDimitry Andric return Builder.CreateSExt(And, ConvertType(E->getType()), "sext");
42710b57cec5SDimitry Andric }
42720b57cec5SDimitry Andric
4273af732203SDimitry Andric bool InstrumentRegions = CGF.CGM.getCodeGenOpts().hasProfileClangInstr();
42740b57cec5SDimitry Andric llvm::Type *ResTy = ConvertType(E->getType());
42750b57cec5SDimitry Andric
42760b57cec5SDimitry Andric // If we have 0 && RHS, see if we can elide RHS, if so, just return 0.
42770b57cec5SDimitry Andric // If we have 1 && X, just emit X without inserting the control flow.
42780b57cec5SDimitry Andric bool LHSCondVal;
42790b57cec5SDimitry Andric if (CGF.ConstantFoldsToSimpleInteger(E->getLHS(), LHSCondVal)) {
42800b57cec5SDimitry Andric if (LHSCondVal) { // If we have 1 && X, just emit X.
42810b57cec5SDimitry Andric CGF.incrementProfileCounter(E);
42820b57cec5SDimitry Andric
42830b57cec5SDimitry Andric Value *RHSCond = CGF.EvaluateExprAsBool(E->getRHS());
4284af732203SDimitry Andric
4285af732203SDimitry Andric // If we're generating for profiling or coverage, generate a branch to a
4286af732203SDimitry Andric // block that increments the RHS counter needed to track branch condition
4287af732203SDimitry Andric // coverage. In this case, use "FBlock" as both the final "TrueBlock" and
4288af732203SDimitry Andric // "FalseBlock" after the increment is done.
4289af732203SDimitry Andric if (InstrumentRegions &&
4290af732203SDimitry Andric CodeGenFunction::isInstrumentedCondition(E->getRHS())) {
4291af732203SDimitry Andric llvm::BasicBlock *FBlock = CGF.createBasicBlock("land.end");
4292af732203SDimitry Andric llvm::BasicBlock *RHSBlockCnt = CGF.createBasicBlock("land.rhscnt");
4293af732203SDimitry Andric Builder.CreateCondBr(RHSCond, RHSBlockCnt, FBlock);
4294af732203SDimitry Andric CGF.EmitBlock(RHSBlockCnt);
4295af732203SDimitry Andric CGF.incrementProfileCounter(E->getRHS());
4296af732203SDimitry Andric CGF.EmitBranch(FBlock);
4297af732203SDimitry Andric CGF.EmitBlock(FBlock);
4298af732203SDimitry Andric }
4299af732203SDimitry Andric
43000b57cec5SDimitry Andric // ZExt result to int or bool.
43010b57cec5SDimitry Andric return Builder.CreateZExtOrBitCast(RHSCond, ResTy, "land.ext");
43020b57cec5SDimitry Andric }
43030b57cec5SDimitry Andric
43040b57cec5SDimitry Andric // 0 && RHS: If it is safe, just elide the RHS, and return 0/false.
43050b57cec5SDimitry Andric if (!CGF.ContainsLabel(E->getRHS()))
43060b57cec5SDimitry Andric return llvm::Constant::getNullValue(ResTy);
43070b57cec5SDimitry Andric }
43080b57cec5SDimitry Andric
43090b57cec5SDimitry Andric llvm::BasicBlock *ContBlock = CGF.createBasicBlock("land.end");
43100b57cec5SDimitry Andric llvm::BasicBlock *RHSBlock = CGF.createBasicBlock("land.rhs");
43110b57cec5SDimitry Andric
43120b57cec5SDimitry Andric CodeGenFunction::ConditionalEvaluation eval(CGF);
43130b57cec5SDimitry Andric
43140b57cec5SDimitry Andric // Branch on the LHS first. If it is false, go to the failure (cont) block.
43150b57cec5SDimitry Andric CGF.EmitBranchOnBoolExpr(E->getLHS(), RHSBlock, ContBlock,
43160b57cec5SDimitry Andric CGF.getProfileCount(E->getRHS()));
43170b57cec5SDimitry Andric
43180b57cec5SDimitry Andric // Any edges into the ContBlock are now from an (indeterminate number of)
43190b57cec5SDimitry Andric // edges from this first condition. All of these values will be false. Start
43200b57cec5SDimitry Andric // setting up the PHI node in the Cont Block for this.
43210b57cec5SDimitry Andric llvm::PHINode *PN = llvm::PHINode::Create(llvm::Type::getInt1Ty(VMContext), 2,
43220b57cec5SDimitry Andric "", ContBlock);
43230b57cec5SDimitry Andric for (llvm::pred_iterator PI = pred_begin(ContBlock), PE = pred_end(ContBlock);
43240b57cec5SDimitry Andric PI != PE; ++PI)
43250b57cec5SDimitry Andric PN->addIncoming(llvm::ConstantInt::getFalse(VMContext), *PI);
43260b57cec5SDimitry Andric
43270b57cec5SDimitry Andric eval.begin(CGF);
43280b57cec5SDimitry Andric CGF.EmitBlock(RHSBlock);
43290b57cec5SDimitry Andric CGF.incrementProfileCounter(E);
43300b57cec5SDimitry Andric Value *RHSCond = CGF.EvaluateExprAsBool(E->getRHS());
43310b57cec5SDimitry Andric eval.end(CGF);
43320b57cec5SDimitry Andric
43330b57cec5SDimitry Andric // Reaquire the RHS block, as there may be subblocks inserted.
43340b57cec5SDimitry Andric RHSBlock = Builder.GetInsertBlock();
43350b57cec5SDimitry Andric
4336af732203SDimitry Andric // If we're generating for profiling or coverage, generate a branch on the
4337af732203SDimitry Andric // RHS to a block that increments the RHS true counter needed to track branch
4338af732203SDimitry Andric // condition coverage.
4339af732203SDimitry Andric if (InstrumentRegions &&
4340af732203SDimitry Andric CodeGenFunction::isInstrumentedCondition(E->getRHS())) {
4341af732203SDimitry Andric llvm::BasicBlock *RHSBlockCnt = CGF.createBasicBlock("land.rhscnt");
4342af732203SDimitry Andric Builder.CreateCondBr(RHSCond, RHSBlockCnt, ContBlock);
4343af732203SDimitry Andric CGF.EmitBlock(RHSBlockCnt);
4344af732203SDimitry Andric CGF.incrementProfileCounter(E->getRHS());
4345af732203SDimitry Andric CGF.EmitBranch(ContBlock);
4346af732203SDimitry Andric PN->addIncoming(RHSCond, RHSBlockCnt);
4347af732203SDimitry Andric }
4348af732203SDimitry Andric
43490b57cec5SDimitry Andric // Emit an unconditional branch from this block to ContBlock.
43500b57cec5SDimitry Andric {
43510b57cec5SDimitry Andric // There is no need to emit line number for unconditional branch.
43520b57cec5SDimitry Andric auto NL = ApplyDebugLocation::CreateEmpty(CGF);
43530b57cec5SDimitry Andric CGF.EmitBlock(ContBlock);
43540b57cec5SDimitry Andric }
43550b57cec5SDimitry Andric // Insert an entry into the phi node for the edge with the value of RHSCond.
43560b57cec5SDimitry Andric PN->addIncoming(RHSCond, RHSBlock);
43570b57cec5SDimitry Andric
43580b57cec5SDimitry Andric // Artificial location to preserve the scope information
43590b57cec5SDimitry Andric {
43600b57cec5SDimitry Andric auto NL = ApplyDebugLocation::CreateArtificial(CGF);
43610b57cec5SDimitry Andric PN->setDebugLoc(Builder.getCurrentDebugLocation());
43620b57cec5SDimitry Andric }
43630b57cec5SDimitry Andric
43640b57cec5SDimitry Andric // ZExt result to int.
43650b57cec5SDimitry Andric return Builder.CreateZExtOrBitCast(PN, ResTy, "land.ext");
43660b57cec5SDimitry Andric }
43670b57cec5SDimitry Andric
VisitBinLOr(const BinaryOperator * E)43680b57cec5SDimitry Andric Value *ScalarExprEmitter::VisitBinLOr(const BinaryOperator *E) {
43690b57cec5SDimitry Andric // Perform vector logical or on comparisons with zero vectors.
43700b57cec5SDimitry Andric if (E->getType()->isVectorType()) {
43710b57cec5SDimitry Andric CGF.incrementProfileCounter(E);
43720b57cec5SDimitry Andric
43730b57cec5SDimitry Andric Value *LHS = Visit(E->getLHS());
43740b57cec5SDimitry Andric Value *RHS = Visit(E->getRHS());
43750b57cec5SDimitry Andric Value *Zero = llvm::ConstantAggregateZero::get(LHS->getType());
43760b57cec5SDimitry Andric if (LHS->getType()->isFPOrFPVectorTy()) {
43775ffd83dbSDimitry Andric CodeGenFunction::CGFPOptionsRAII FPOptsRAII(
43785ffd83dbSDimitry Andric CGF, E->getFPFeaturesInEffect(CGF.getLangOpts()));
43790b57cec5SDimitry Andric LHS = Builder.CreateFCmp(llvm::CmpInst::FCMP_UNE, LHS, Zero, "cmp");
43800b57cec5SDimitry Andric RHS = Builder.CreateFCmp(llvm::CmpInst::FCMP_UNE, RHS, Zero, "cmp");
43810b57cec5SDimitry Andric } else {
43820b57cec5SDimitry Andric LHS = Builder.CreateICmp(llvm::CmpInst::ICMP_NE, LHS, Zero, "cmp");
43830b57cec5SDimitry Andric RHS = Builder.CreateICmp(llvm::CmpInst::ICMP_NE, RHS, Zero, "cmp");
43840b57cec5SDimitry Andric }
43850b57cec5SDimitry Andric Value *Or = Builder.CreateOr(LHS, RHS);
43860b57cec5SDimitry Andric return Builder.CreateSExt(Or, ConvertType(E->getType()), "sext");
43870b57cec5SDimitry Andric }
43880b57cec5SDimitry Andric
4389af732203SDimitry Andric bool InstrumentRegions = CGF.CGM.getCodeGenOpts().hasProfileClangInstr();
43900b57cec5SDimitry Andric llvm::Type *ResTy = ConvertType(E->getType());
43910b57cec5SDimitry Andric
43920b57cec5SDimitry Andric // If we have 1 || RHS, see if we can elide RHS, if so, just return 1.
43930b57cec5SDimitry Andric // If we have 0 || X, just emit X without inserting the control flow.
43940b57cec5SDimitry Andric bool LHSCondVal;
43950b57cec5SDimitry Andric if (CGF.ConstantFoldsToSimpleInteger(E->getLHS(), LHSCondVal)) {
43960b57cec5SDimitry Andric if (!LHSCondVal) { // If we have 0 || X, just emit X.
43970b57cec5SDimitry Andric CGF.incrementProfileCounter(E);
43980b57cec5SDimitry Andric
43990b57cec5SDimitry Andric Value *RHSCond = CGF.EvaluateExprAsBool(E->getRHS());
4400af732203SDimitry Andric
4401af732203SDimitry Andric // If we're generating for profiling or coverage, generate a branch to a
4402af732203SDimitry Andric // block that increments the RHS counter need to track branch condition
4403af732203SDimitry Andric // coverage. In this case, use "FBlock" as both the final "TrueBlock" and
4404af732203SDimitry Andric // "FalseBlock" after the increment is done.
4405af732203SDimitry Andric if (InstrumentRegions &&
4406af732203SDimitry Andric CodeGenFunction::isInstrumentedCondition(E->getRHS())) {
4407af732203SDimitry Andric llvm::BasicBlock *FBlock = CGF.createBasicBlock("lor.end");
4408af732203SDimitry Andric llvm::BasicBlock *RHSBlockCnt = CGF.createBasicBlock("lor.rhscnt");
4409af732203SDimitry Andric Builder.CreateCondBr(RHSCond, FBlock, RHSBlockCnt);
4410af732203SDimitry Andric CGF.EmitBlock(RHSBlockCnt);
4411af732203SDimitry Andric CGF.incrementProfileCounter(E->getRHS());
4412af732203SDimitry Andric CGF.EmitBranch(FBlock);
4413af732203SDimitry Andric CGF.EmitBlock(FBlock);
4414af732203SDimitry Andric }
4415af732203SDimitry Andric
44160b57cec5SDimitry Andric // ZExt result to int or bool.
44170b57cec5SDimitry Andric return Builder.CreateZExtOrBitCast(RHSCond, ResTy, "lor.ext");
44180b57cec5SDimitry Andric }
44190b57cec5SDimitry Andric
44200b57cec5SDimitry Andric // 1 || RHS: If it is safe, just elide the RHS, and return 1/true.
44210b57cec5SDimitry Andric if (!CGF.ContainsLabel(E->getRHS()))
44220b57cec5SDimitry Andric return llvm::ConstantInt::get(ResTy, 1);
44230b57cec5SDimitry Andric }
44240b57cec5SDimitry Andric
44250b57cec5SDimitry Andric llvm::BasicBlock *ContBlock = CGF.createBasicBlock("lor.end");
44260b57cec5SDimitry Andric llvm::BasicBlock *RHSBlock = CGF.createBasicBlock("lor.rhs");
44270b57cec5SDimitry Andric
44280b57cec5SDimitry Andric CodeGenFunction::ConditionalEvaluation eval(CGF);
44290b57cec5SDimitry Andric
44300b57cec5SDimitry Andric // Branch on the LHS first. If it is true, go to the success (cont) block.
44310b57cec5SDimitry Andric CGF.EmitBranchOnBoolExpr(E->getLHS(), ContBlock, RHSBlock,
44320b57cec5SDimitry Andric CGF.getCurrentProfileCount() -
44330b57cec5SDimitry Andric CGF.getProfileCount(E->getRHS()));
44340b57cec5SDimitry Andric
44350b57cec5SDimitry Andric // Any edges into the ContBlock are now from an (indeterminate number of)
44360b57cec5SDimitry Andric // edges from this first condition. All of these values will be true. Start
44370b57cec5SDimitry Andric // setting up the PHI node in the Cont Block for this.
44380b57cec5SDimitry Andric llvm::PHINode *PN = llvm::PHINode::Create(llvm::Type::getInt1Ty(VMContext), 2,
44390b57cec5SDimitry Andric "", ContBlock);
44400b57cec5SDimitry Andric for (llvm::pred_iterator PI = pred_begin(ContBlock), PE = pred_end(ContBlock);
44410b57cec5SDimitry Andric PI != PE; ++PI)
44420b57cec5SDimitry Andric PN->addIncoming(llvm::ConstantInt::getTrue(VMContext), *PI);
44430b57cec5SDimitry Andric
44440b57cec5SDimitry Andric eval.begin(CGF);
44450b57cec5SDimitry Andric
44460b57cec5SDimitry Andric // Emit the RHS condition as a bool value.
44470b57cec5SDimitry Andric CGF.EmitBlock(RHSBlock);
44480b57cec5SDimitry Andric CGF.incrementProfileCounter(E);
44490b57cec5SDimitry Andric Value *RHSCond = CGF.EvaluateExprAsBool(E->getRHS());
44500b57cec5SDimitry Andric
44510b57cec5SDimitry Andric eval.end(CGF);
44520b57cec5SDimitry Andric
44530b57cec5SDimitry Andric // Reaquire the RHS block, as there may be subblocks inserted.
44540b57cec5SDimitry Andric RHSBlock = Builder.GetInsertBlock();
44550b57cec5SDimitry Andric
4456af732203SDimitry Andric // If we're generating for profiling or coverage, generate a branch on the
4457af732203SDimitry Andric // RHS to a block that increments the RHS true counter needed to track branch
4458af732203SDimitry Andric // condition coverage.
4459af732203SDimitry Andric if (InstrumentRegions &&
4460af732203SDimitry Andric CodeGenFunction::isInstrumentedCondition(E->getRHS())) {
4461af732203SDimitry Andric llvm::BasicBlock *RHSBlockCnt = CGF.createBasicBlock("lor.rhscnt");
4462af732203SDimitry Andric Builder.CreateCondBr(RHSCond, ContBlock, RHSBlockCnt);
4463af732203SDimitry Andric CGF.EmitBlock(RHSBlockCnt);
4464af732203SDimitry Andric CGF.incrementProfileCounter(E->getRHS());
4465af732203SDimitry Andric CGF.EmitBranch(ContBlock);
4466af732203SDimitry Andric PN->addIncoming(RHSCond, RHSBlockCnt);
4467af732203SDimitry Andric }
4468af732203SDimitry Andric
44690b57cec5SDimitry Andric // Emit an unconditional branch from this block to ContBlock. Insert an entry
44700b57cec5SDimitry Andric // into the phi node for the edge with the value of RHSCond.
44710b57cec5SDimitry Andric CGF.EmitBlock(ContBlock);
44720b57cec5SDimitry Andric PN->addIncoming(RHSCond, RHSBlock);
44730b57cec5SDimitry Andric
44740b57cec5SDimitry Andric // ZExt result to int.
44750b57cec5SDimitry Andric return Builder.CreateZExtOrBitCast(PN, ResTy, "lor.ext");
44760b57cec5SDimitry Andric }
44770b57cec5SDimitry Andric
VisitBinComma(const BinaryOperator * E)44780b57cec5SDimitry Andric Value *ScalarExprEmitter::VisitBinComma(const BinaryOperator *E) {
44790b57cec5SDimitry Andric CGF.EmitIgnoredExpr(E->getLHS());
44800b57cec5SDimitry Andric CGF.EnsureInsertPoint();
44810b57cec5SDimitry Andric return Visit(E->getRHS());
44820b57cec5SDimitry Andric }
44830b57cec5SDimitry Andric
44840b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
44850b57cec5SDimitry Andric // Other Operators
44860b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
44870b57cec5SDimitry Andric
44880b57cec5SDimitry Andric /// isCheapEnoughToEvaluateUnconditionally - Return true if the specified
44890b57cec5SDimitry Andric /// expression is cheap enough and side-effect-free enough to evaluate
44900b57cec5SDimitry Andric /// unconditionally instead of conditionally. This is used to convert control
44910b57cec5SDimitry Andric /// flow into selects in some cases.
isCheapEnoughToEvaluateUnconditionally(const Expr * E,CodeGenFunction & CGF)44920b57cec5SDimitry Andric static bool isCheapEnoughToEvaluateUnconditionally(const Expr *E,
44930b57cec5SDimitry Andric CodeGenFunction &CGF) {
44940b57cec5SDimitry Andric // Anything that is an integer or floating point constant is fine.
44950b57cec5SDimitry Andric return E->IgnoreParens()->isEvaluatable(CGF.getContext());
44960b57cec5SDimitry Andric
44970b57cec5SDimitry Andric // Even non-volatile automatic variables can't be evaluated unconditionally.
44980b57cec5SDimitry Andric // Referencing a thread_local may cause non-trivial initialization work to
44990b57cec5SDimitry Andric // occur. If we're inside a lambda and one of the variables is from the scope
45000b57cec5SDimitry Andric // outside the lambda, that function may have returned already. Reading its
45010b57cec5SDimitry Andric // locals is a bad idea. Also, these reads may introduce races there didn't
45020b57cec5SDimitry Andric // exist in the source-level program.
45030b57cec5SDimitry Andric }
45040b57cec5SDimitry Andric
45050b57cec5SDimitry Andric
45060b57cec5SDimitry Andric Value *ScalarExprEmitter::
VisitAbstractConditionalOperator(const AbstractConditionalOperator * E)45070b57cec5SDimitry Andric VisitAbstractConditionalOperator(const AbstractConditionalOperator *E) {
45080b57cec5SDimitry Andric TestAndClearIgnoreResultAssign();
45090b57cec5SDimitry Andric
45100b57cec5SDimitry Andric // Bind the common expression if necessary.
45110b57cec5SDimitry Andric CodeGenFunction::OpaqueValueMapping binding(CGF, E);
45120b57cec5SDimitry Andric
45130b57cec5SDimitry Andric Expr *condExpr = E->getCond();
45140b57cec5SDimitry Andric Expr *lhsExpr = E->getTrueExpr();
45150b57cec5SDimitry Andric Expr *rhsExpr = E->getFalseExpr();
45160b57cec5SDimitry Andric
45170b57cec5SDimitry Andric // If the condition constant folds and can be elided, try to avoid emitting
45180b57cec5SDimitry Andric // the condition and the dead arm.
45190b57cec5SDimitry Andric bool CondExprBool;
45200b57cec5SDimitry Andric if (CGF.ConstantFoldsToSimpleInteger(condExpr, CondExprBool)) {
45210b57cec5SDimitry Andric Expr *live = lhsExpr, *dead = rhsExpr;
45220b57cec5SDimitry Andric if (!CondExprBool) std::swap(live, dead);
45230b57cec5SDimitry Andric
45240b57cec5SDimitry Andric // If the dead side doesn't have labels we need, just emit the Live part.
45250b57cec5SDimitry Andric if (!CGF.ContainsLabel(dead)) {
45260b57cec5SDimitry Andric if (CondExprBool)
45270b57cec5SDimitry Andric CGF.incrementProfileCounter(E);
45280b57cec5SDimitry Andric Value *Result = Visit(live);
45290b57cec5SDimitry Andric
45300b57cec5SDimitry Andric // If the live part is a throw expression, it acts like it has a void
45310b57cec5SDimitry Andric // type, so evaluating it returns a null Value*. However, a conditional
45320b57cec5SDimitry Andric // with non-void type must return a non-null Value*.
45330b57cec5SDimitry Andric if (!Result && !E->getType()->isVoidType())
45340b57cec5SDimitry Andric Result = llvm::UndefValue::get(CGF.ConvertType(E->getType()));
45350b57cec5SDimitry Andric
45360b57cec5SDimitry Andric return Result;
45370b57cec5SDimitry Andric }
45380b57cec5SDimitry Andric }
45390b57cec5SDimitry Andric
45400b57cec5SDimitry Andric // OpenCL: If the condition is a vector, we can treat this condition like
45410b57cec5SDimitry Andric // the select function.
45425ffd83dbSDimitry Andric if ((CGF.getLangOpts().OpenCL && condExpr->getType()->isVectorType()) ||
45435ffd83dbSDimitry Andric condExpr->getType()->isExtVectorType()) {
45440b57cec5SDimitry Andric CGF.incrementProfileCounter(E);
45450b57cec5SDimitry Andric
45460b57cec5SDimitry Andric llvm::Value *CondV = CGF.EmitScalarExpr(condExpr);
45470b57cec5SDimitry Andric llvm::Value *LHS = Visit(lhsExpr);
45480b57cec5SDimitry Andric llvm::Value *RHS = Visit(rhsExpr);
45490b57cec5SDimitry Andric
45500b57cec5SDimitry Andric llvm::Type *condType = ConvertType(condExpr->getType());
4551af732203SDimitry Andric auto *vecTy = cast<llvm::FixedVectorType>(condType);
45520b57cec5SDimitry Andric
45530b57cec5SDimitry Andric unsigned numElem = vecTy->getNumElements();
45540b57cec5SDimitry Andric llvm::Type *elemType = vecTy->getElementType();
45550b57cec5SDimitry Andric
45560b57cec5SDimitry Andric llvm::Value *zeroVec = llvm::Constant::getNullValue(vecTy);
45570b57cec5SDimitry Andric llvm::Value *TestMSB = Builder.CreateICmpSLT(CondV, zeroVec);
45585ffd83dbSDimitry Andric llvm::Value *tmp = Builder.CreateSExt(
45595ffd83dbSDimitry Andric TestMSB, llvm::FixedVectorType::get(elemType, numElem), "sext");
45600b57cec5SDimitry Andric llvm::Value *tmp2 = Builder.CreateNot(tmp);
45610b57cec5SDimitry Andric
45620b57cec5SDimitry Andric // Cast float to int to perform ANDs if necessary.
45630b57cec5SDimitry Andric llvm::Value *RHSTmp = RHS;
45640b57cec5SDimitry Andric llvm::Value *LHSTmp = LHS;
45650b57cec5SDimitry Andric bool wasCast = false;
45660b57cec5SDimitry Andric llvm::VectorType *rhsVTy = cast<llvm::VectorType>(RHS->getType());
45670b57cec5SDimitry Andric if (rhsVTy->getElementType()->isFloatingPointTy()) {
45680b57cec5SDimitry Andric RHSTmp = Builder.CreateBitCast(RHS, tmp2->getType());
45690b57cec5SDimitry Andric LHSTmp = Builder.CreateBitCast(LHS, tmp->getType());
45700b57cec5SDimitry Andric wasCast = true;
45710b57cec5SDimitry Andric }
45720b57cec5SDimitry Andric
45730b57cec5SDimitry Andric llvm::Value *tmp3 = Builder.CreateAnd(RHSTmp, tmp2);
45740b57cec5SDimitry Andric llvm::Value *tmp4 = Builder.CreateAnd(LHSTmp, tmp);
45750b57cec5SDimitry Andric llvm::Value *tmp5 = Builder.CreateOr(tmp3, tmp4, "cond");
45760b57cec5SDimitry Andric if (wasCast)
45770b57cec5SDimitry Andric tmp5 = Builder.CreateBitCast(tmp5, RHS->getType());
45780b57cec5SDimitry Andric
45790b57cec5SDimitry Andric return tmp5;
45800b57cec5SDimitry Andric }
45810b57cec5SDimitry Andric
4582480093f4SDimitry Andric if (condExpr->getType()->isVectorType()) {
4583480093f4SDimitry Andric CGF.incrementProfileCounter(E);
4584480093f4SDimitry Andric
4585480093f4SDimitry Andric llvm::Value *CondV = CGF.EmitScalarExpr(condExpr);
4586480093f4SDimitry Andric llvm::Value *LHS = Visit(lhsExpr);
4587480093f4SDimitry Andric llvm::Value *RHS = Visit(rhsExpr);
4588480093f4SDimitry Andric
4589480093f4SDimitry Andric llvm::Type *CondType = ConvertType(condExpr->getType());
4590480093f4SDimitry Andric auto *VecTy = cast<llvm::VectorType>(CondType);
4591480093f4SDimitry Andric llvm::Value *ZeroVec = llvm::Constant::getNullValue(VecTy);
4592480093f4SDimitry Andric
4593480093f4SDimitry Andric CondV = Builder.CreateICmpNE(CondV, ZeroVec, "vector_cond");
4594480093f4SDimitry Andric return Builder.CreateSelect(CondV, LHS, RHS, "vector_select");
4595480093f4SDimitry Andric }
4596480093f4SDimitry Andric
45970b57cec5SDimitry Andric // If this is a really simple expression (like x ? 4 : 5), emit this as a
45980b57cec5SDimitry Andric // select instead of as control flow. We can only do this if it is cheap and
45990b57cec5SDimitry Andric // safe to evaluate the LHS and RHS unconditionally.
46000b57cec5SDimitry Andric if (isCheapEnoughToEvaluateUnconditionally(lhsExpr, CGF) &&
46010b57cec5SDimitry Andric isCheapEnoughToEvaluateUnconditionally(rhsExpr, CGF)) {
46020b57cec5SDimitry Andric llvm::Value *CondV = CGF.EvaluateExprAsBool(condExpr);
46030b57cec5SDimitry Andric llvm::Value *StepV = Builder.CreateZExtOrBitCast(CondV, CGF.Int64Ty);
46040b57cec5SDimitry Andric
46050b57cec5SDimitry Andric CGF.incrementProfileCounter(E, StepV);
46060b57cec5SDimitry Andric
46070b57cec5SDimitry Andric llvm::Value *LHS = Visit(lhsExpr);
46080b57cec5SDimitry Andric llvm::Value *RHS = Visit(rhsExpr);
46090b57cec5SDimitry Andric if (!LHS) {
46100b57cec5SDimitry Andric // If the conditional has void type, make sure we return a null Value*.
46110b57cec5SDimitry Andric assert(!RHS && "LHS and RHS types must match");
46120b57cec5SDimitry Andric return nullptr;
46130b57cec5SDimitry Andric }
46140b57cec5SDimitry Andric return Builder.CreateSelect(CondV, LHS, RHS, "cond");
46150b57cec5SDimitry Andric }
46160b57cec5SDimitry Andric
46170b57cec5SDimitry Andric llvm::BasicBlock *LHSBlock = CGF.createBasicBlock("cond.true");
46180b57cec5SDimitry Andric llvm::BasicBlock *RHSBlock = CGF.createBasicBlock("cond.false");
46190b57cec5SDimitry Andric llvm::BasicBlock *ContBlock = CGF.createBasicBlock("cond.end");
46200b57cec5SDimitry Andric
46210b57cec5SDimitry Andric CodeGenFunction::ConditionalEvaluation eval(CGF);
46220b57cec5SDimitry Andric CGF.EmitBranchOnBoolExpr(condExpr, LHSBlock, RHSBlock,
46230b57cec5SDimitry Andric CGF.getProfileCount(lhsExpr));
46240b57cec5SDimitry Andric
46250b57cec5SDimitry Andric CGF.EmitBlock(LHSBlock);
46260b57cec5SDimitry Andric CGF.incrementProfileCounter(E);
46270b57cec5SDimitry Andric eval.begin(CGF);
46280b57cec5SDimitry Andric Value *LHS = Visit(lhsExpr);
46290b57cec5SDimitry Andric eval.end(CGF);
46300b57cec5SDimitry Andric
46310b57cec5SDimitry Andric LHSBlock = Builder.GetInsertBlock();
46320b57cec5SDimitry Andric Builder.CreateBr(ContBlock);
46330b57cec5SDimitry Andric
46340b57cec5SDimitry Andric CGF.EmitBlock(RHSBlock);
46350b57cec5SDimitry Andric eval.begin(CGF);
46360b57cec5SDimitry Andric Value *RHS = Visit(rhsExpr);
46370b57cec5SDimitry Andric eval.end(CGF);
46380b57cec5SDimitry Andric
46390b57cec5SDimitry Andric RHSBlock = Builder.GetInsertBlock();
46400b57cec5SDimitry Andric CGF.EmitBlock(ContBlock);
46410b57cec5SDimitry Andric
46420b57cec5SDimitry Andric // If the LHS or RHS is a throw expression, it will be legitimately null.
46430b57cec5SDimitry Andric if (!LHS)
46440b57cec5SDimitry Andric return RHS;
46450b57cec5SDimitry Andric if (!RHS)
46460b57cec5SDimitry Andric return LHS;
46470b57cec5SDimitry Andric
46480b57cec5SDimitry Andric // Create a PHI node for the real part.
46490b57cec5SDimitry Andric llvm::PHINode *PN = Builder.CreatePHI(LHS->getType(), 2, "cond");
46500b57cec5SDimitry Andric PN->addIncoming(LHS, LHSBlock);
46510b57cec5SDimitry Andric PN->addIncoming(RHS, RHSBlock);
46520b57cec5SDimitry Andric return PN;
46530b57cec5SDimitry Andric }
46540b57cec5SDimitry Andric
VisitChooseExpr(ChooseExpr * E)46550b57cec5SDimitry Andric Value *ScalarExprEmitter::VisitChooseExpr(ChooseExpr *E) {
46560b57cec5SDimitry Andric return Visit(E->getChosenSubExpr());
46570b57cec5SDimitry Andric }
46580b57cec5SDimitry Andric
VisitVAArgExpr(VAArgExpr * VE)46590b57cec5SDimitry Andric Value *ScalarExprEmitter::VisitVAArgExpr(VAArgExpr *VE) {
46600b57cec5SDimitry Andric QualType Ty = VE->getType();
46610b57cec5SDimitry Andric
46620b57cec5SDimitry Andric if (Ty->isVariablyModifiedType())
46630b57cec5SDimitry Andric CGF.EmitVariablyModifiedType(Ty);
46640b57cec5SDimitry Andric
46650b57cec5SDimitry Andric Address ArgValue = Address::invalid();
46660b57cec5SDimitry Andric Address ArgPtr = CGF.EmitVAArg(VE, ArgValue);
46670b57cec5SDimitry Andric
46680b57cec5SDimitry Andric llvm::Type *ArgTy = ConvertType(VE->getType());
46690b57cec5SDimitry Andric
46700b57cec5SDimitry Andric // If EmitVAArg fails, emit an error.
46710b57cec5SDimitry Andric if (!ArgPtr.isValid()) {
46720b57cec5SDimitry Andric CGF.ErrorUnsupported(VE, "va_arg expression");
46730b57cec5SDimitry Andric return llvm::UndefValue::get(ArgTy);
46740b57cec5SDimitry Andric }
46750b57cec5SDimitry Andric
46760b57cec5SDimitry Andric // FIXME Volatility.
46770b57cec5SDimitry Andric llvm::Value *Val = Builder.CreateLoad(ArgPtr);
46780b57cec5SDimitry Andric
46790b57cec5SDimitry Andric // If EmitVAArg promoted the type, we must truncate it.
46800b57cec5SDimitry Andric if (ArgTy != Val->getType()) {
46810b57cec5SDimitry Andric if (ArgTy->isPointerTy() && !Val->getType()->isPointerTy())
46820b57cec5SDimitry Andric Val = Builder.CreateIntToPtr(Val, ArgTy);
46830b57cec5SDimitry Andric else
46840b57cec5SDimitry Andric Val = Builder.CreateTrunc(Val, ArgTy);
46850b57cec5SDimitry Andric }
46860b57cec5SDimitry Andric
46870b57cec5SDimitry Andric return Val;
46880b57cec5SDimitry Andric }
46890b57cec5SDimitry Andric
VisitBlockExpr(const BlockExpr * block)46900b57cec5SDimitry Andric Value *ScalarExprEmitter::VisitBlockExpr(const BlockExpr *block) {
46910b57cec5SDimitry Andric return CGF.EmitBlockLiteral(block);
46920b57cec5SDimitry Andric }
46930b57cec5SDimitry Andric
46940b57cec5SDimitry Andric // Convert a vec3 to vec4, or vice versa.
ConvertVec3AndVec4(CGBuilderTy & Builder,CodeGenFunction & CGF,Value * Src,unsigned NumElementsDst)46950b57cec5SDimitry Andric static Value *ConvertVec3AndVec4(CGBuilderTy &Builder, CodeGenFunction &CGF,
46960b57cec5SDimitry Andric Value *Src, unsigned NumElementsDst) {
46975ffd83dbSDimitry Andric static constexpr int Mask[] = {0, 1, 2, -1};
4698af732203SDimitry Andric return Builder.CreateShuffleVector(Src,
46995ffd83dbSDimitry Andric llvm::makeArrayRef(Mask, NumElementsDst));
47000b57cec5SDimitry Andric }
47010b57cec5SDimitry Andric
47020b57cec5SDimitry Andric // Create cast instructions for converting LLVM value \p Src to LLVM type \p
47030b57cec5SDimitry Andric // DstTy. \p Src has the same size as \p DstTy. Both are single value types
47040b57cec5SDimitry Andric // but could be scalar or vectors of different lengths, and either can be
47050b57cec5SDimitry Andric // pointer.
47060b57cec5SDimitry Andric // There are 4 cases:
47070b57cec5SDimitry Andric // 1. non-pointer -> non-pointer : needs 1 bitcast
47080b57cec5SDimitry Andric // 2. pointer -> pointer : needs 1 bitcast or addrspacecast
47090b57cec5SDimitry Andric // 3. pointer -> non-pointer
47100b57cec5SDimitry Andric // a) pointer -> intptr_t : needs 1 ptrtoint
47110b57cec5SDimitry Andric // b) pointer -> non-intptr_t : needs 1 ptrtoint then 1 bitcast
47120b57cec5SDimitry Andric // 4. non-pointer -> pointer
47130b57cec5SDimitry Andric // a) intptr_t -> pointer : needs 1 inttoptr
47140b57cec5SDimitry Andric // b) non-intptr_t -> pointer : needs 1 bitcast then 1 inttoptr
47150b57cec5SDimitry Andric // Note: for cases 3b and 4b two casts are required since LLVM casts do not
47160b57cec5SDimitry Andric // allow casting directly between pointer types and non-integer non-pointer
47170b57cec5SDimitry Andric // types.
createCastsForTypeOfSameSize(CGBuilderTy & Builder,const llvm::DataLayout & DL,Value * Src,llvm::Type * DstTy,StringRef Name="")47180b57cec5SDimitry Andric static Value *createCastsForTypeOfSameSize(CGBuilderTy &Builder,
47190b57cec5SDimitry Andric const llvm::DataLayout &DL,
47200b57cec5SDimitry Andric Value *Src, llvm::Type *DstTy,
47210b57cec5SDimitry Andric StringRef Name = "") {
47220b57cec5SDimitry Andric auto SrcTy = Src->getType();
47230b57cec5SDimitry Andric
47240b57cec5SDimitry Andric // Case 1.
47250b57cec5SDimitry Andric if (!SrcTy->isPointerTy() && !DstTy->isPointerTy())
47260b57cec5SDimitry Andric return Builder.CreateBitCast(Src, DstTy, Name);
47270b57cec5SDimitry Andric
47280b57cec5SDimitry Andric // Case 2.
47290b57cec5SDimitry Andric if (SrcTy->isPointerTy() && DstTy->isPointerTy())
47300b57cec5SDimitry Andric return Builder.CreatePointerBitCastOrAddrSpaceCast(Src, DstTy, Name);
47310b57cec5SDimitry Andric
47320b57cec5SDimitry Andric // Case 3.
47330b57cec5SDimitry Andric if (SrcTy->isPointerTy() && !DstTy->isPointerTy()) {
47340b57cec5SDimitry Andric // Case 3b.
47350b57cec5SDimitry Andric if (!DstTy->isIntegerTy())
47360b57cec5SDimitry Andric Src = Builder.CreatePtrToInt(Src, DL.getIntPtrType(SrcTy));
47370b57cec5SDimitry Andric // Cases 3a and 3b.
47380b57cec5SDimitry Andric return Builder.CreateBitOrPointerCast(Src, DstTy, Name);
47390b57cec5SDimitry Andric }
47400b57cec5SDimitry Andric
47410b57cec5SDimitry Andric // Case 4b.
47420b57cec5SDimitry Andric if (!SrcTy->isIntegerTy())
47430b57cec5SDimitry Andric Src = Builder.CreateBitCast(Src, DL.getIntPtrType(DstTy));
47440b57cec5SDimitry Andric // Cases 4a and 4b.
47450b57cec5SDimitry Andric return Builder.CreateIntToPtr(Src, DstTy, Name);
47460b57cec5SDimitry Andric }
47470b57cec5SDimitry Andric
VisitAsTypeExpr(AsTypeExpr * E)47480b57cec5SDimitry Andric Value *ScalarExprEmitter::VisitAsTypeExpr(AsTypeExpr *E) {
47490b57cec5SDimitry Andric Value *Src = CGF.EmitScalarExpr(E->getSrcExpr());
47500b57cec5SDimitry Andric llvm::Type *DstTy = ConvertType(E->getType());
47510b57cec5SDimitry Andric
47520b57cec5SDimitry Andric llvm::Type *SrcTy = Src->getType();
4753af732203SDimitry Andric unsigned NumElementsSrc =
4754af732203SDimitry Andric isa<llvm::VectorType>(SrcTy)
4755af732203SDimitry Andric ? cast<llvm::FixedVectorType>(SrcTy)->getNumElements()
4756af732203SDimitry Andric : 0;
4757af732203SDimitry Andric unsigned NumElementsDst =
4758af732203SDimitry Andric isa<llvm::VectorType>(DstTy)
4759af732203SDimitry Andric ? cast<llvm::FixedVectorType>(DstTy)->getNumElements()
4760af732203SDimitry Andric : 0;
47610b57cec5SDimitry Andric
47620b57cec5SDimitry Andric // Going from vec3 to non-vec3 is a special case and requires a shuffle
47630b57cec5SDimitry Andric // vector to get a vec4, then a bitcast if the target type is different.
47640b57cec5SDimitry Andric if (NumElementsSrc == 3 && NumElementsDst != 3) {
47650b57cec5SDimitry Andric Src = ConvertVec3AndVec4(Builder, CGF, Src, 4);
47660b57cec5SDimitry Andric
47670b57cec5SDimitry Andric if (!CGF.CGM.getCodeGenOpts().PreserveVec3Type) {
47680b57cec5SDimitry Andric Src = createCastsForTypeOfSameSize(Builder, CGF.CGM.getDataLayout(), Src,
47690b57cec5SDimitry Andric DstTy);
47700b57cec5SDimitry Andric }
47710b57cec5SDimitry Andric
47720b57cec5SDimitry Andric Src->setName("astype");
47730b57cec5SDimitry Andric return Src;
47740b57cec5SDimitry Andric }
47750b57cec5SDimitry Andric
47760b57cec5SDimitry Andric // Going from non-vec3 to vec3 is a special case and requires a bitcast
47770b57cec5SDimitry Andric // to vec4 if the original type is not vec4, then a shuffle vector to
47780b57cec5SDimitry Andric // get a vec3.
47790b57cec5SDimitry Andric if (NumElementsSrc != 3 && NumElementsDst == 3) {
47800b57cec5SDimitry Andric if (!CGF.CGM.getCodeGenOpts().PreserveVec3Type) {
47815ffd83dbSDimitry Andric auto *Vec4Ty = llvm::FixedVectorType::get(
47825ffd83dbSDimitry Andric cast<llvm::VectorType>(DstTy)->getElementType(), 4);
47830b57cec5SDimitry Andric Src = createCastsForTypeOfSameSize(Builder, CGF.CGM.getDataLayout(), Src,
47840b57cec5SDimitry Andric Vec4Ty);
47850b57cec5SDimitry Andric }
47860b57cec5SDimitry Andric
47870b57cec5SDimitry Andric Src = ConvertVec3AndVec4(Builder, CGF, Src, 3);
47880b57cec5SDimitry Andric Src->setName("astype");
47890b57cec5SDimitry Andric return Src;
47900b57cec5SDimitry Andric }
47910b57cec5SDimitry Andric
4792a7dea167SDimitry Andric return createCastsForTypeOfSameSize(Builder, CGF.CGM.getDataLayout(),
47930b57cec5SDimitry Andric Src, DstTy, "astype");
47940b57cec5SDimitry Andric }
47950b57cec5SDimitry Andric
VisitAtomicExpr(AtomicExpr * E)47960b57cec5SDimitry Andric Value *ScalarExprEmitter::VisitAtomicExpr(AtomicExpr *E) {
47970b57cec5SDimitry Andric return CGF.EmitAtomicExpr(E).getScalarVal();
47980b57cec5SDimitry Andric }
47990b57cec5SDimitry Andric
48000b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
48010b57cec5SDimitry Andric // Entry Point into this File
48020b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
48030b57cec5SDimitry Andric
48040b57cec5SDimitry Andric /// Emit the computation of the specified expression of scalar type, ignoring
48050b57cec5SDimitry Andric /// the result.
EmitScalarExpr(const Expr * E,bool IgnoreResultAssign)48060b57cec5SDimitry Andric Value *CodeGenFunction::EmitScalarExpr(const Expr *E, bool IgnoreResultAssign) {
48070b57cec5SDimitry Andric assert(E && hasScalarEvaluationKind(E->getType()) &&
48080b57cec5SDimitry Andric "Invalid scalar expression to emit");
48090b57cec5SDimitry Andric
48100b57cec5SDimitry Andric return ScalarExprEmitter(*this, IgnoreResultAssign)
48110b57cec5SDimitry Andric .Visit(const_cast<Expr *>(E));
48120b57cec5SDimitry Andric }
48130b57cec5SDimitry Andric
48140b57cec5SDimitry Andric /// Emit a conversion from the specified type to the specified destination type,
48150b57cec5SDimitry Andric /// both of which are LLVM scalar types.
EmitScalarConversion(Value * Src,QualType SrcTy,QualType DstTy,SourceLocation Loc)48160b57cec5SDimitry Andric Value *CodeGenFunction::EmitScalarConversion(Value *Src, QualType SrcTy,
48170b57cec5SDimitry Andric QualType DstTy,
48180b57cec5SDimitry Andric SourceLocation Loc) {
48190b57cec5SDimitry Andric assert(hasScalarEvaluationKind(SrcTy) && hasScalarEvaluationKind(DstTy) &&
48200b57cec5SDimitry Andric "Invalid scalar expression to emit");
48210b57cec5SDimitry Andric return ScalarExprEmitter(*this).EmitScalarConversion(Src, SrcTy, DstTy, Loc);
48220b57cec5SDimitry Andric }
48230b57cec5SDimitry Andric
48240b57cec5SDimitry Andric /// Emit a conversion from the specified complex type to the specified
48250b57cec5SDimitry Andric /// destination type, where the destination type is an LLVM scalar type.
EmitComplexToScalarConversion(ComplexPairTy Src,QualType SrcTy,QualType DstTy,SourceLocation Loc)48260b57cec5SDimitry Andric Value *CodeGenFunction::EmitComplexToScalarConversion(ComplexPairTy Src,
48270b57cec5SDimitry Andric QualType SrcTy,
48280b57cec5SDimitry Andric QualType DstTy,
48290b57cec5SDimitry Andric SourceLocation Loc) {
48300b57cec5SDimitry Andric assert(SrcTy->isAnyComplexType() && hasScalarEvaluationKind(DstTy) &&
48310b57cec5SDimitry Andric "Invalid complex -> scalar conversion");
48320b57cec5SDimitry Andric return ScalarExprEmitter(*this)
48330b57cec5SDimitry Andric .EmitComplexToScalarConversion(Src, SrcTy, DstTy, Loc);
48340b57cec5SDimitry Andric }
48350b57cec5SDimitry Andric
48360b57cec5SDimitry Andric
48370b57cec5SDimitry Andric llvm::Value *CodeGenFunction::
EmitScalarPrePostIncDec(const UnaryOperator * E,LValue LV,bool isInc,bool isPre)48380b57cec5SDimitry Andric EmitScalarPrePostIncDec(const UnaryOperator *E, LValue LV,
48390b57cec5SDimitry Andric bool isInc, bool isPre) {
48400b57cec5SDimitry Andric return ScalarExprEmitter(*this).EmitScalarPrePostIncDec(E, LV, isInc, isPre);
48410b57cec5SDimitry Andric }
48420b57cec5SDimitry Andric
EmitObjCIsaExpr(const ObjCIsaExpr * E)48430b57cec5SDimitry Andric LValue CodeGenFunction::EmitObjCIsaExpr(const ObjCIsaExpr *E) {
48440b57cec5SDimitry Andric // object->isa or (*object).isa
48450b57cec5SDimitry Andric // Generate code as for: *(Class*)object
48460b57cec5SDimitry Andric
48470b57cec5SDimitry Andric Expr *BaseExpr = E->getBase();
48480b57cec5SDimitry Andric Address Addr = Address::invalid();
4849*5f7ddb14SDimitry Andric if (BaseExpr->isPRValue()) {
48500b57cec5SDimitry Andric Addr = Address(EmitScalarExpr(BaseExpr), getPointerAlign());
48510b57cec5SDimitry Andric } else {
4852480093f4SDimitry Andric Addr = EmitLValue(BaseExpr).getAddress(*this);
48530b57cec5SDimitry Andric }
48540b57cec5SDimitry Andric
48550b57cec5SDimitry Andric // Cast the address to Class*.
48560b57cec5SDimitry Andric Addr = Builder.CreateElementBitCast(Addr, ConvertType(E->getType()));
48570b57cec5SDimitry Andric return MakeAddrLValue(Addr, E->getType());
48580b57cec5SDimitry Andric }
48590b57cec5SDimitry Andric
48600b57cec5SDimitry Andric
EmitCompoundAssignmentLValue(const CompoundAssignOperator * E)48610b57cec5SDimitry Andric LValue CodeGenFunction::EmitCompoundAssignmentLValue(
48620b57cec5SDimitry Andric const CompoundAssignOperator *E) {
48630b57cec5SDimitry Andric ScalarExprEmitter Scalar(*this);
48640b57cec5SDimitry Andric Value *Result = nullptr;
48650b57cec5SDimitry Andric switch (E->getOpcode()) {
48660b57cec5SDimitry Andric #define COMPOUND_OP(Op) \
48670b57cec5SDimitry Andric case BO_##Op##Assign: \
48680b57cec5SDimitry Andric return Scalar.EmitCompoundAssignLValue(E, &ScalarExprEmitter::Emit##Op, \
48690b57cec5SDimitry Andric Result)
48700b57cec5SDimitry Andric COMPOUND_OP(Mul);
48710b57cec5SDimitry Andric COMPOUND_OP(Div);
48720b57cec5SDimitry Andric COMPOUND_OP(Rem);
48730b57cec5SDimitry Andric COMPOUND_OP(Add);
48740b57cec5SDimitry Andric COMPOUND_OP(Sub);
48750b57cec5SDimitry Andric COMPOUND_OP(Shl);
48760b57cec5SDimitry Andric COMPOUND_OP(Shr);
48770b57cec5SDimitry Andric COMPOUND_OP(And);
48780b57cec5SDimitry Andric COMPOUND_OP(Xor);
48790b57cec5SDimitry Andric COMPOUND_OP(Or);
48800b57cec5SDimitry Andric #undef COMPOUND_OP
48810b57cec5SDimitry Andric
48820b57cec5SDimitry Andric case BO_PtrMemD:
48830b57cec5SDimitry Andric case BO_PtrMemI:
48840b57cec5SDimitry Andric case BO_Mul:
48850b57cec5SDimitry Andric case BO_Div:
48860b57cec5SDimitry Andric case BO_Rem:
48870b57cec5SDimitry Andric case BO_Add:
48880b57cec5SDimitry Andric case BO_Sub:
48890b57cec5SDimitry Andric case BO_Shl:
48900b57cec5SDimitry Andric case BO_Shr:
48910b57cec5SDimitry Andric case BO_LT:
48920b57cec5SDimitry Andric case BO_GT:
48930b57cec5SDimitry Andric case BO_LE:
48940b57cec5SDimitry Andric case BO_GE:
48950b57cec5SDimitry Andric case BO_EQ:
48960b57cec5SDimitry Andric case BO_NE:
48970b57cec5SDimitry Andric case BO_Cmp:
48980b57cec5SDimitry Andric case BO_And:
48990b57cec5SDimitry Andric case BO_Xor:
49000b57cec5SDimitry Andric case BO_Or:
49010b57cec5SDimitry Andric case BO_LAnd:
49020b57cec5SDimitry Andric case BO_LOr:
49030b57cec5SDimitry Andric case BO_Assign:
49040b57cec5SDimitry Andric case BO_Comma:
49050b57cec5SDimitry Andric llvm_unreachable("Not valid compound assignment operators");
49060b57cec5SDimitry Andric }
49070b57cec5SDimitry Andric
49080b57cec5SDimitry Andric llvm_unreachable("Unhandled compound assignment operator");
49090b57cec5SDimitry Andric }
49100b57cec5SDimitry Andric
4911a7dea167SDimitry Andric struct GEPOffsetAndOverflow {
4912a7dea167SDimitry Andric // The total (signed) byte offset for the GEP.
4913a7dea167SDimitry Andric llvm::Value *TotalOffset;
4914a7dea167SDimitry Andric // The offset overflow flag - true if the total offset overflows.
4915a7dea167SDimitry Andric llvm::Value *OffsetOverflows;
4916a7dea167SDimitry Andric };
49170b57cec5SDimitry Andric
4918a7dea167SDimitry Andric /// Evaluate given GEPVal, which is either an inbounds GEP, or a constant,
4919a7dea167SDimitry Andric /// and compute the total offset it applies from it's base pointer BasePtr.
4920a7dea167SDimitry Andric /// Returns offset in bytes and a boolean flag whether an overflow happened
4921a7dea167SDimitry Andric /// during evaluation.
EmitGEPOffsetInBytes(Value * BasePtr,Value * GEPVal,llvm::LLVMContext & VMContext,CodeGenModule & CGM,CGBuilderTy & Builder)4922a7dea167SDimitry Andric static GEPOffsetAndOverflow EmitGEPOffsetInBytes(Value *BasePtr, Value *GEPVal,
4923a7dea167SDimitry Andric llvm::LLVMContext &VMContext,
4924a7dea167SDimitry Andric CodeGenModule &CGM,
49255ffd83dbSDimitry Andric CGBuilderTy &Builder) {
4926a7dea167SDimitry Andric const auto &DL = CGM.getDataLayout();
49270b57cec5SDimitry Andric
4928a7dea167SDimitry Andric // The total (signed) byte offset for the GEP.
4929a7dea167SDimitry Andric llvm::Value *TotalOffset = nullptr;
49300b57cec5SDimitry Andric
4931a7dea167SDimitry Andric // Was the GEP already reduced to a constant?
4932a7dea167SDimitry Andric if (isa<llvm::Constant>(GEPVal)) {
4933a7dea167SDimitry Andric // Compute the offset by casting both pointers to integers and subtracting:
4934a7dea167SDimitry Andric // GEPVal = BasePtr + ptr(Offset) <--> Offset = int(GEPVal) - int(BasePtr)
4935a7dea167SDimitry Andric Value *BasePtr_int =
4936a7dea167SDimitry Andric Builder.CreatePtrToInt(BasePtr, DL.getIntPtrType(BasePtr->getType()));
4937a7dea167SDimitry Andric Value *GEPVal_int =
4938a7dea167SDimitry Andric Builder.CreatePtrToInt(GEPVal, DL.getIntPtrType(GEPVal->getType()));
4939a7dea167SDimitry Andric TotalOffset = Builder.CreateSub(GEPVal_int, BasePtr_int);
4940a7dea167SDimitry Andric return {TotalOffset, /*OffsetOverflows=*/Builder.getFalse()};
4941a7dea167SDimitry Andric }
49420b57cec5SDimitry Andric
49430b57cec5SDimitry Andric auto *GEP = cast<llvm::GEPOperator>(GEPVal);
4944a7dea167SDimitry Andric assert(GEP->getPointerOperand() == BasePtr &&
4945a7dea167SDimitry Andric "BasePtr must be the the base of the GEP.");
49460b57cec5SDimitry Andric assert(GEP->isInBounds() && "Expected inbounds GEP");
49470b57cec5SDimitry Andric
49480b57cec5SDimitry Andric auto *IntPtrTy = DL.getIntPtrType(GEP->getPointerOperandType());
49490b57cec5SDimitry Andric
49500b57cec5SDimitry Andric // Grab references to the signed add/mul overflow intrinsics for intptr_t.
49510b57cec5SDimitry Andric auto *Zero = llvm::ConstantInt::getNullValue(IntPtrTy);
49520b57cec5SDimitry Andric auto *SAddIntrinsic =
49530b57cec5SDimitry Andric CGM.getIntrinsic(llvm::Intrinsic::sadd_with_overflow, IntPtrTy);
49540b57cec5SDimitry Andric auto *SMulIntrinsic =
49550b57cec5SDimitry Andric CGM.getIntrinsic(llvm::Intrinsic::smul_with_overflow, IntPtrTy);
49560b57cec5SDimitry Andric
49570b57cec5SDimitry Andric // The offset overflow flag - true if the total offset overflows.
49580b57cec5SDimitry Andric llvm::Value *OffsetOverflows = Builder.getFalse();
49590b57cec5SDimitry Andric
49600b57cec5SDimitry Andric /// Return the result of the given binary operation.
49610b57cec5SDimitry Andric auto eval = [&](BinaryOperator::Opcode Opcode, llvm::Value *LHS,
49620b57cec5SDimitry Andric llvm::Value *RHS) -> llvm::Value * {
49630b57cec5SDimitry Andric assert((Opcode == BO_Add || Opcode == BO_Mul) && "Can't eval binop");
49640b57cec5SDimitry Andric
49650b57cec5SDimitry Andric // If the operands are constants, return a constant result.
49660b57cec5SDimitry Andric if (auto *LHSCI = dyn_cast<llvm::ConstantInt>(LHS)) {
49670b57cec5SDimitry Andric if (auto *RHSCI = dyn_cast<llvm::ConstantInt>(RHS)) {
49680b57cec5SDimitry Andric llvm::APInt N;
49690b57cec5SDimitry Andric bool HasOverflow = mayHaveIntegerOverflow(LHSCI, RHSCI, Opcode,
49700b57cec5SDimitry Andric /*Signed=*/true, N);
49710b57cec5SDimitry Andric if (HasOverflow)
49720b57cec5SDimitry Andric OffsetOverflows = Builder.getTrue();
49730b57cec5SDimitry Andric return llvm::ConstantInt::get(VMContext, N);
49740b57cec5SDimitry Andric }
49750b57cec5SDimitry Andric }
49760b57cec5SDimitry Andric
49770b57cec5SDimitry Andric // Otherwise, compute the result with checked arithmetic.
49780b57cec5SDimitry Andric auto *ResultAndOverflow = Builder.CreateCall(
49790b57cec5SDimitry Andric (Opcode == BO_Add) ? SAddIntrinsic : SMulIntrinsic, {LHS, RHS});
49800b57cec5SDimitry Andric OffsetOverflows = Builder.CreateOr(
49810b57cec5SDimitry Andric Builder.CreateExtractValue(ResultAndOverflow, 1), OffsetOverflows);
49820b57cec5SDimitry Andric return Builder.CreateExtractValue(ResultAndOverflow, 0);
49830b57cec5SDimitry Andric };
49840b57cec5SDimitry Andric
49850b57cec5SDimitry Andric // Determine the total byte offset by looking at each GEP operand.
49860b57cec5SDimitry Andric for (auto GTI = llvm::gep_type_begin(GEP), GTE = llvm::gep_type_end(GEP);
49870b57cec5SDimitry Andric GTI != GTE; ++GTI) {
49880b57cec5SDimitry Andric llvm::Value *LocalOffset;
49890b57cec5SDimitry Andric auto *Index = GTI.getOperand();
49900b57cec5SDimitry Andric // Compute the local offset contributed by this indexing step:
49910b57cec5SDimitry Andric if (auto *STy = GTI.getStructTypeOrNull()) {
49920b57cec5SDimitry Andric // For struct indexing, the local offset is the byte position of the
49930b57cec5SDimitry Andric // specified field.
49940b57cec5SDimitry Andric unsigned FieldNo = cast<llvm::ConstantInt>(Index)->getZExtValue();
49950b57cec5SDimitry Andric LocalOffset = llvm::ConstantInt::get(
49960b57cec5SDimitry Andric IntPtrTy, DL.getStructLayout(STy)->getElementOffset(FieldNo));
49970b57cec5SDimitry Andric } else {
49980b57cec5SDimitry Andric // Otherwise this is array-like indexing. The local offset is the index
49990b57cec5SDimitry Andric // multiplied by the element size.
50000b57cec5SDimitry Andric auto *ElementSize = llvm::ConstantInt::get(
50010b57cec5SDimitry Andric IntPtrTy, DL.getTypeAllocSize(GTI.getIndexedType()));
50020b57cec5SDimitry Andric auto *IndexS = Builder.CreateIntCast(Index, IntPtrTy, /*isSigned=*/true);
50030b57cec5SDimitry Andric LocalOffset = eval(BO_Mul, ElementSize, IndexS);
50040b57cec5SDimitry Andric }
50050b57cec5SDimitry Andric
50060b57cec5SDimitry Andric // If this is the first offset, set it as the total offset. Otherwise, add
50070b57cec5SDimitry Andric // the local offset into the running total.
50080b57cec5SDimitry Andric if (!TotalOffset || TotalOffset == Zero)
50090b57cec5SDimitry Andric TotalOffset = LocalOffset;
50100b57cec5SDimitry Andric else
50110b57cec5SDimitry Andric TotalOffset = eval(BO_Add, TotalOffset, LocalOffset);
50120b57cec5SDimitry Andric }
50130b57cec5SDimitry Andric
5014a7dea167SDimitry Andric return {TotalOffset, OffsetOverflows};
5015a7dea167SDimitry Andric }
5016a7dea167SDimitry Andric
5017a7dea167SDimitry Andric Value *
EmitCheckedInBoundsGEP(Value * Ptr,ArrayRef<Value * > IdxList,bool SignedIndices,bool IsSubtraction,SourceLocation Loc,const Twine & Name)5018a7dea167SDimitry Andric CodeGenFunction::EmitCheckedInBoundsGEP(Value *Ptr, ArrayRef<Value *> IdxList,
5019a7dea167SDimitry Andric bool SignedIndices, bool IsSubtraction,
5020a7dea167SDimitry Andric SourceLocation Loc, const Twine &Name) {
5021*5f7ddb14SDimitry Andric llvm::Type *PtrTy = Ptr->getType();
5022*5f7ddb14SDimitry Andric Value *GEPVal = Builder.CreateInBoundsGEP(
5023*5f7ddb14SDimitry Andric PtrTy->getPointerElementType(), Ptr, IdxList, Name);
5024a7dea167SDimitry Andric
5025a7dea167SDimitry Andric // If the pointer overflow sanitizer isn't enabled, do nothing.
5026a7dea167SDimitry Andric if (!SanOpts.has(SanitizerKind::PointerOverflow))
5027a7dea167SDimitry Andric return GEPVal;
5028a7dea167SDimitry Andric
5029a7dea167SDimitry Andric // Perform nullptr-and-offset check unless the nullptr is defined.
5030a7dea167SDimitry Andric bool PerformNullCheck = !NullPointerIsDefined(
5031a7dea167SDimitry Andric Builder.GetInsertBlock()->getParent(), PtrTy->getPointerAddressSpace());
5032a7dea167SDimitry Andric // Check for overflows unless the GEP got constant-folded,
5033a7dea167SDimitry Andric // and only in the default address space
5034a7dea167SDimitry Andric bool PerformOverflowCheck =
5035a7dea167SDimitry Andric !isa<llvm::Constant>(GEPVal) && PtrTy->getPointerAddressSpace() == 0;
5036a7dea167SDimitry Andric
5037a7dea167SDimitry Andric if (!(PerformNullCheck || PerformOverflowCheck))
5038a7dea167SDimitry Andric return GEPVal;
5039a7dea167SDimitry Andric
5040a7dea167SDimitry Andric const auto &DL = CGM.getDataLayout();
5041a7dea167SDimitry Andric
5042a7dea167SDimitry Andric SanitizerScope SanScope(this);
5043a7dea167SDimitry Andric llvm::Type *IntPtrTy = DL.getIntPtrType(PtrTy);
5044a7dea167SDimitry Andric
5045a7dea167SDimitry Andric GEPOffsetAndOverflow EvaluatedGEP =
5046a7dea167SDimitry Andric EmitGEPOffsetInBytes(Ptr, GEPVal, getLLVMContext(), CGM, Builder);
5047a7dea167SDimitry Andric
5048a7dea167SDimitry Andric assert((!isa<llvm::Constant>(EvaluatedGEP.TotalOffset) ||
5049a7dea167SDimitry Andric EvaluatedGEP.OffsetOverflows == Builder.getFalse()) &&
5050a7dea167SDimitry Andric "If the offset got constant-folded, we don't expect that there was an "
5051a7dea167SDimitry Andric "overflow.");
5052a7dea167SDimitry Andric
5053a7dea167SDimitry Andric auto *Zero = llvm::ConstantInt::getNullValue(IntPtrTy);
5054a7dea167SDimitry Andric
5055a7dea167SDimitry Andric // Common case: if the total offset is zero, and we are using C++ semantics,
5056a7dea167SDimitry Andric // where nullptr+0 is defined, don't emit a check.
5057a7dea167SDimitry Andric if (EvaluatedGEP.TotalOffset == Zero && CGM.getLangOpts().CPlusPlus)
50580b57cec5SDimitry Andric return GEPVal;
50590b57cec5SDimitry Andric
50600b57cec5SDimitry Andric // Now that we've computed the total offset, add it to the base pointer (with
50610b57cec5SDimitry Andric // wrapping semantics).
5062a7dea167SDimitry Andric auto *IntPtr = Builder.CreatePtrToInt(Ptr, IntPtrTy);
5063a7dea167SDimitry Andric auto *ComputedGEP = Builder.CreateAdd(IntPtr, EvaluatedGEP.TotalOffset);
50640b57cec5SDimitry Andric
5065a7dea167SDimitry Andric llvm::SmallVector<std::pair<llvm::Value *, SanitizerMask>, 2> Checks;
5066a7dea167SDimitry Andric
5067a7dea167SDimitry Andric if (PerformNullCheck) {
5068a7dea167SDimitry Andric // In C++, if the base pointer evaluates to a null pointer value,
5069a7dea167SDimitry Andric // the only valid pointer this inbounds GEP can produce is also
5070a7dea167SDimitry Andric // a null pointer, so the offset must also evaluate to zero.
5071a7dea167SDimitry Andric // Likewise, if we have non-zero base pointer, we can not get null pointer
5072a7dea167SDimitry Andric // as a result, so the offset can not be -intptr_t(BasePtr).
5073a7dea167SDimitry Andric // In other words, both pointers are either null, or both are non-null,
5074a7dea167SDimitry Andric // or the behaviour is undefined.
5075a7dea167SDimitry Andric //
5076a7dea167SDimitry Andric // C, however, is more strict in this regard, and gives more
5077a7dea167SDimitry Andric // optimization opportunities: in C, additionally, nullptr+0 is undefined.
5078a7dea167SDimitry Andric // So both the input to the 'gep inbounds' AND the output must not be null.
5079a7dea167SDimitry Andric auto *BaseIsNotNullptr = Builder.CreateIsNotNull(Ptr);
5080a7dea167SDimitry Andric auto *ResultIsNotNullptr = Builder.CreateIsNotNull(ComputedGEP);
5081a7dea167SDimitry Andric auto *Valid =
5082a7dea167SDimitry Andric CGM.getLangOpts().CPlusPlus
5083a7dea167SDimitry Andric ? Builder.CreateICmpEQ(BaseIsNotNullptr, ResultIsNotNullptr)
5084a7dea167SDimitry Andric : Builder.CreateAnd(BaseIsNotNullptr, ResultIsNotNullptr);
5085a7dea167SDimitry Andric Checks.emplace_back(Valid, SanitizerKind::PointerOverflow);
5086a7dea167SDimitry Andric }
5087a7dea167SDimitry Andric
5088a7dea167SDimitry Andric if (PerformOverflowCheck) {
50890b57cec5SDimitry Andric // The GEP is valid if:
50900b57cec5SDimitry Andric // 1) The total offset doesn't overflow, and
50910b57cec5SDimitry Andric // 2) The sign of the difference between the computed address and the base
50920b57cec5SDimitry Andric // pointer matches the sign of the total offset.
50930b57cec5SDimitry Andric llvm::Value *ValidGEP;
5094a7dea167SDimitry Andric auto *NoOffsetOverflow = Builder.CreateNot(EvaluatedGEP.OffsetOverflows);
50950b57cec5SDimitry Andric if (SignedIndices) {
5096a7dea167SDimitry Andric // GEP is computed as `unsigned base + signed offset`, therefore:
5097a7dea167SDimitry Andric // * If offset was positive, then the computed pointer can not be
5098a7dea167SDimitry Andric // [unsigned] less than the base pointer, unless it overflowed.
5099a7dea167SDimitry Andric // * If offset was negative, then the computed pointer can not be
5100a7dea167SDimitry Andric // [unsigned] greater than the bas pointere, unless it overflowed.
51010b57cec5SDimitry Andric auto *PosOrZeroValid = Builder.CreateICmpUGE(ComputedGEP, IntPtr);
5102a7dea167SDimitry Andric auto *PosOrZeroOffset =
5103a7dea167SDimitry Andric Builder.CreateICmpSGE(EvaluatedGEP.TotalOffset, Zero);
51040b57cec5SDimitry Andric llvm::Value *NegValid = Builder.CreateICmpULT(ComputedGEP, IntPtr);
5105a7dea167SDimitry Andric ValidGEP =
5106a7dea167SDimitry Andric Builder.CreateSelect(PosOrZeroOffset, PosOrZeroValid, NegValid);
5107a7dea167SDimitry Andric } else if (!IsSubtraction) {
5108a7dea167SDimitry Andric // GEP is computed as `unsigned base + unsigned offset`, therefore the
5109a7dea167SDimitry Andric // computed pointer can not be [unsigned] less than base pointer,
5110a7dea167SDimitry Andric // unless there was an overflow.
5111a7dea167SDimitry Andric // Equivalent to `@llvm.uadd.with.overflow(%base, %offset)`.
5112a7dea167SDimitry Andric ValidGEP = Builder.CreateICmpUGE(ComputedGEP, IntPtr);
51130b57cec5SDimitry Andric } else {
5114a7dea167SDimitry Andric // GEP is computed as `unsigned base - unsigned offset`, therefore the
5115a7dea167SDimitry Andric // computed pointer can not be [unsigned] greater than base pointer,
5116a7dea167SDimitry Andric // unless there was an overflow.
5117a7dea167SDimitry Andric // Equivalent to `@llvm.usub.with.overflow(%base, sub(0, %offset))`.
5118a7dea167SDimitry Andric ValidGEP = Builder.CreateICmpULE(ComputedGEP, IntPtr);
51190b57cec5SDimitry Andric }
5120a7dea167SDimitry Andric ValidGEP = Builder.CreateAnd(ValidGEP, NoOffsetOverflow);
5121a7dea167SDimitry Andric Checks.emplace_back(ValidGEP, SanitizerKind::PointerOverflow);
5122a7dea167SDimitry Andric }
5123a7dea167SDimitry Andric
5124a7dea167SDimitry Andric assert(!Checks.empty() && "Should have produced some checks.");
51250b57cec5SDimitry Andric
51260b57cec5SDimitry Andric llvm::Constant *StaticArgs[] = {EmitCheckSourceLocation(Loc)};
51270b57cec5SDimitry Andric // Pass the computed GEP to the runtime to avoid emitting poisoned arguments.
51280b57cec5SDimitry Andric llvm::Value *DynamicArgs[] = {IntPtr, ComputedGEP};
5129a7dea167SDimitry Andric EmitCheck(Checks, SanitizerHandler::PointerOverflow, StaticArgs, DynamicArgs);
51300b57cec5SDimitry Andric
51310b57cec5SDimitry Andric return GEPVal;
51320b57cec5SDimitry Andric }
5133