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