diff options
Diffstat (limited to 'clang/lib/CodeGen/CGCall.cpp')
| -rw-r--r-- | clang/lib/CodeGen/CGCall.cpp | 115 | 
1 files changed, 87 insertions, 28 deletions
diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp index b74f6f942426..e4803fde230f 100644 --- a/clang/lib/CodeGen/CGCall.cpp +++ b/clang/lib/CodeGen/CGCall.cpp @@ -19,6 +19,7 @@  #include "CodeGenFunction.h"  #include "CodeGenModule.h"  #include "TargetInfo.h" +#include "clang/AST/Attr.h"  #include "clang/AST/Decl.h"  #include "clang/AST/DeclCXX.h"  #include "clang/AST/DeclObjC.h" @@ -28,7 +29,6 @@  #include "clang/CodeGen/CGFunctionInfo.h"  #include "clang/CodeGen/SwiftCallingConv.h"  #include "llvm/ADT/StringExtras.h" -#include "llvm/Transforms/Utils/Local.h"  #include "llvm/Analysis/ValueTracking.h"  #include "llvm/IR/Attributes.h"  #include "llvm/IR/CallingConv.h" @@ -36,6 +36,7 @@  #include "llvm/IR/InlineAsm.h"  #include "llvm/IR/IntrinsicInst.h"  #include "llvm/IR/Intrinsics.h" +#include "llvm/Transforms/Utils/Local.h"  using namespace clang;  using namespace CodeGen; @@ -1020,13 +1021,13 @@ void CodeGenFunction::ExpandTypeFromArgs(    auto Exp = getTypeExpansion(Ty, getContext());    if (auto CAExp = dyn_cast<ConstantArrayExpansion>(Exp.get())) { -    forConstantArrayExpansion(*this, CAExp, LV.getAddress(), -                              [&](Address EltAddr) { -      LValue LV = MakeAddrLValue(EltAddr, CAExp->EltTy); -      ExpandTypeFromArgs(CAExp->EltTy, LV, AI); -    }); +    forConstantArrayExpansion( +        *this, CAExp, LV.getAddress(*this), [&](Address EltAddr) { +          LValue LV = MakeAddrLValue(EltAddr, CAExp->EltTy); +          ExpandTypeFromArgs(CAExp->EltTy, LV, AI); +        });    } else if (auto RExp = dyn_cast<RecordExpansion>(Exp.get())) { -    Address This = LV.getAddress(); +    Address This = LV.getAddress(*this);      for (const CXXBaseSpecifier *BS : RExp->Bases) {        // Perform a single step derived-to-base conversion.        Address Base = @@ -1047,8 +1048,13 @@ void CodeGenFunction::ExpandTypeFromArgs(      auto imagValue = *AI++;      EmitStoreOfComplex(ComplexPairTy(realValue, imagValue), LV, /*init*/ true);    } else { +    // Call EmitStoreOfScalar except when the lvalue is a bitfield to emit a +    // primitive store.      assert(isa<NoExpansion>(Exp.get())); -    EmitStoreThroughLValue(RValue::get(*AI++), LV); +    if (LV.isBitField()) +      EmitStoreThroughLValue(RValue::get(*AI++), LV); +    else +      EmitStoreOfScalar(*AI++, LV);    }  } @@ -1057,7 +1063,7 @@ void CodeGenFunction::ExpandTypeToArgs(      SmallVectorImpl<llvm::Value *> &IRCallArgs, unsigned &IRCallArgPos) {    auto Exp = getTypeExpansion(Ty, getContext());    if (auto CAExp = dyn_cast<ConstantArrayExpansion>(Exp.get())) { -    Address Addr = Arg.hasLValue() ? Arg.getKnownLValue().getAddress() +    Address Addr = Arg.hasLValue() ? Arg.getKnownLValue().getAddress(*this)                                     : Arg.getKnownRValue().getAggregateAddress();      forConstantArrayExpansion(          *this, CAExp, Addr, [&](Address EltAddr) { @@ -1068,7 +1074,7 @@ void CodeGenFunction::ExpandTypeToArgs(                             IRCallArgPos);          });    } else if (auto RExp = dyn_cast<RecordExpansion>(Exp.get())) { -    Address This = Arg.hasLValue() ? Arg.getKnownLValue().getAddress() +    Address This = Arg.hasLValue() ? Arg.getKnownLValue().getAddress(*this)                                     : Arg.getKnownRValue().getAggregateAddress();      for (const CXXBaseSpecifier *BS : RExp->Bases) {        // Perform a single step derived-to-base conversion. @@ -1305,6 +1311,15 @@ static void CreateCoercedStore(llvm::Value *Src,      DstTy = Dst.getType()->getElementType();    } +  llvm::PointerType *SrcPtrTy = llvm::dyn_cast<llvm::PointerType>(SrcTy); +  llvm::PointerType *DstPtrTy = llvm::dyn_cast<llvm::PointerType>(DstTy); +  if (SrcPtrTy && DstPtrTy && +      SrcPtrTy->getAddressSpace() != DstPtrTy->getAddressSpace()) { +    Src = CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(Src, DstTy); +    CGF.Builder.CreateStore(Src, Dst, DstIsVolatile); +    return; +  } +    // If the source and destination are integer or pointer types, just do an    // extension or truncation to the desired type.    if ((isa<llvm::IntegerType>(SrcTy) || isa<llvm::PointerType>(SrcTy)) && @@ -1732,8 +1747,9 @@ void CodeGenModule::ConstructDefaultFnAttrList(StringRef Name, bool HasOptnone,      if (CodeGenOpts.NullPointerIsValid)        FuncAttrs.addAttribute("null-pointer-is-valid", "true"); -    if (!CodeGenOpts.FPDenormalMode.empty()) -      FuncAttrs.addAttribute("denormal-fp-math", CodeGenOpts.FPDenormalMode); +    if (CodeGenOpts.FPDenormalMode != llvm::DenormalMode::Invalid) +      FuncAttrs.addAttribute("denormal-fp-math", +                             llvm::denormalModeName(CodeGenOpts.FPDenormalMode));      FuncAttrs.addAttribute("no-trapping-math",                             llvm::toStringRef(CodeGenOpts.NoTrappingMath)); @@ -1853,11 +1869,30 @@ void CodeGenModule::ConstructAttributeList(      if (const FunctionDecl *Fn = dyn_cast<FunctionDecl>(TargetDecl)) {        AddAttributesFromFunctionProtoType(            getContext(), FuncAttrs, Fn->getType()->getAs<FunctionProtoType>()); -      // Don't use [[noreturn]] or _Noreturn for a call to a virtual function. -      // These attributes are not inherited by overloads.        const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(Fn); -      if (Fn->isNoReturn() && !(AttrOnCallSite && MD && MD->isVirtual())) -        FuncAttrs.addAttribute(llvm::Attribute::NoReturn); +      const bool IsVirtualCall = MD && MD->isVirtual(); +      // Don't use [[noreturn]], _Noreturn or [[no_builtin]] for a call to a +      // virtual function. These attributes are not inherited by overloads. +      if (!(AttrOnCallSite && IsVirtualCall)) { +        if (Fn->isNoReturn()) +          FuncAttrs.addAttribute(llvm::Attribute::NoReturn); + +        const auto *NBA = Fn->getAttr<NoBuiltinAttr>(); +        bool HasWildcard = NBA && llvm::is_contained(NBA->builtinNames(), "*"); +        if (getLangOpts().NoBuiltin || HasWildcard) +          FuncAttrs.addAttribute("no-builtins"); +        else { +          auto AddNoBuiltinAttr = [&FuncAttrs](StringRef BuiltinName) { +            SmallString<32> AttributeName; +            AttributeName += "no-builtin-"; +            AttributeName += BuiltinName; +            FuncAttrs.addAttribute(AttributeName); +          }; +          llvm::for_each(getLangOpts().NoBuiltinFuncs, AddNoBuiltinAttr); +          if (NBA) +            llvm::for_each(NBA->builtinNames(), AddNoBuiltinAttr); +        } +      }      }      // 'const', 'pure' and 'noalias' attributed functions are also nounwind. @@ -3112,7 +3147,7 @@ static bool isProvablyNull(llvm::Value *addr) {  static void emitWriteback(CodeGenFunction &CGF,                            const CallArgList::Writeback &writeback) {    const LValue &srcLV = writeback.Source; -  Address srcAddr = srcLV.getAddress(); +  Address srcAddr = srcLV.getAddress(CGF);    assert(!isProvablyNull(srcAddr.getPointer()) &&           "shouldn't have writeback for provably null argument"); @@ -3220,7 +3255,7 @@ static void emitWritebackArg(CodeGenFunction &CGF, CallArgList &args,        CRE->getSubExpr()->getType()->castAs<PointerType>()->getPointeeType();      srcLV = CGF.MakeAddrLValue(srcAddr, srcAddrType);    } -  Address srcAddr = srcLV.getAddress(); +  Address srcAddr = srcLV.getAddress(CGF);    // The dest and src types don't necessarily match in LLVM terms    // because of the crazy ObjC compatibility rules. @@ -3534,7 +3569,7 @@ RValue CallArg::getRValue(CodeGenFunction &CGF) const {    CGF.EmitAggregateCopy(Copy, LV, Ty, AggValueSlot::DoesNotOverlap,                          LV.isVolatile());    IsUsed = true; -  return RValue::getAggregate(Copy.getAddress()); +  return RValue::getAggregate(Copy.getAddress(CGF));  }  void CallArg::copyInto(CodeGenFunction &CGF, Address Addr) const { @@ -3544,7 +3579,7 @@ void CallArg::copyInto(CodeGenFunction &CGF, Address Addr) const {    else if (!HasLV && RV.isComplex())      CGF.EmitStoreOfComplex(RV.getComplexVal(), Dst, /*init=*/true);    else { -    auto Addr = HasLV ? LV.getAddress() : RV.getAggregateAddress(); +    auto Addr = HasLV ? LV.getAddress(CGF) : RV.getAggregateAddress();      LValue SrcLV = CGF.MakeAddrLValue(Addr, Ty);      // We assume that call args are never copied into subobjects.      CGF.EmitAggregateCopy(Dst, SrcLV, Ty, AggValueSlot::DoesNotOverlap, @@ -3907,7 +3942,7 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo,        if (I->isAggregate()) {          // Replace the placeholder with the appropriate argument slot GEP.          Address Addr = I->hasLValue() -                           ? I->getKnownLValue().getAddress() +                           ? I->getKnownLValue().getAddress(*this)                             : I->getKnownRValue().getAggregateAddress();          llvm::Instruction *Placeholder =              cast<llvm::Instruction>(Addr.getPointer()); @@ -3952,7 +3987,7 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo,          // 3. If the argument is byval, but RV is not located in default          //    or alloca address space.          Address Addr = I->hasLValue() -                           ? I->getKnownLValue().getAddress() +                           ? I->getKnownLValue().getAddress(*this)                             : I->getKnownRValue().getAggregateAddress();          llvm::Value *V = Addr.getPointer();          CharUnits Align = ArgInfo.getIndirectAlign(); @@ -3973,9 +4008,8 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo,            auto LV = I->getKnownLValue();            auto AS = LV.getAddressSpace(); -          if ((!ArgInfo.getIndirectByVal() && -               (LV.getAlignment() >= -                getContext().getTypeAlignInChars(I->Ty)))) { +          if (!ArgInfo.getIndirectByVal() || +              (LV.getAlignment() < getContext().getTypeAlignInChars(I->Ty))) {              NeedCopy = true;            }            if (!getLangOpts().OpenCL) { @@ -4039,7 +4073,7 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo,            V = I->getKnownRValue().getScalarVal();          else            V = Builder.CreateLoad( -              I->hasLValue() ? I->getKnownLValue().getAddress() +              I->hasLValue() ? I->getKnownLValue().getAddress(*this)                               : I->getKnownRValue().getAggregateAddress());          // Implement swifterror by copying into a new swifterror argument. @@ -4082,7 +4116,7 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo,          Src = CreateMemTemp(I->Ty, "coerce");          I->copyInto(*this, Src);        } else { -        Src = I->hasLValue() ? I->getKnownLValue().getAddress() +        Src = I->hasLValue() ? I->getKnownLValue().getAddress(*this)                               : I->getKnownRValue().getAggregateAddress();        } @@ -4137,7 +4171,7 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo,        Address addr = Address::invalid();        Address AllocaAddr = Address::invalid();        if (I->isAggregate()) { -        addr = I->hasLValue() ? I->getKnownLValue().getAddress() +        addr = I->hasLValue() ? I->getKnownLValue().getAddress(*this)                                : I->getKnownRValue().getAggregateAddress();        } else { @@ -4305,6 +4339,13 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo,                               Callee.getAbstractInfo(), Attrs, CallingConv,                               /*AttrOnCallSite=*/true); +  if (const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(CurFuncDecl)) +    if (FD->usesFPIntrin()) +      // All calls within a strictfp function are marked strictfp +      Attrs = +        Attrs.addAttribute(getLLVMContext(), llvm::AttributeList::FunctionIndex, +                           llvm::Attribute::StrictFP); +    // Apply some call-site-specific attributes.    // TODO: work this into building the attribute set. @@ -4354,6 +4395,13 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo,    SmallVector<llvm::OperandBundleDef, 1> BundleList =        getBundlesForFunclet(CalleePtr); +  if (const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(CurFuncDecl)) +    if (FD->usesFPIntrin()) +      // All calls within a strictfp function are marked strictfp +      Attrs = +        Attrs.addAttribute(getLLVMContext(), llvm::AttributeList::FunctionIndex, +                           llvm::Attribute::StrictFP); +    // Emit the actual call/invoke instruction.    llvm::CallBase *CI;    if (!InvokeDest) { @@ -4367,6 +4415,17 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo,    if (callOrInvoke)      *callOrInvoke = CI; +  // If this is within a function that has the guard(nocf) attribute and is an +  // indirect call, add the "guard_nocf" attribute to this call to indicate that +  // Control Flow Guard checks should not be added, even if the call is inlined. +  if (const auto *FD = dyn_cast_or_null<FunctionDecl>(CurFuncDecl)) { +    if (const auto *A = FD->getAttr<CFGuardAttr>()) { +      if (A->getGuard() == CFGuardAttr::GuardArg::nocf && !CI->getCalledFunction()) +        Attrs = Attrs.addAttribute( +            getLLVMContext(), llvm::AttributeList::FunctionIndex, "guard_nocf"); +    } +  } +    // Apply the attributes and calling convention.    CI->setAttributes(Attrs);    CI->setCallingConv(static_cast<llvm::CallingConv::ID>(CallingConv));  | 
