Commit d65bbf81 authored by Guillaume Chatelet's avatar Guillaume Chatelet
Browse files

[clang] Add support for __builtin_memcpy_inline

Summary: This is a follow up on D61634 and the last step to implement http://lists.llvm.org/pipermail/llvm-dev/2019-April/131973.html

Reviewers: efriedma, courbet, tejohnson

Subscribers: hiraditya, cfe-commits, llvm-commits, jdoerfert, t.p.northover

Tags: #clang, #llvm

Differential Revision: https://reviews.llvm.org/D73543
parent fafc6e4f
Loading
Loading
Loading
Loading
+17 −0
Original line number Diff line number Diff line
@@ -2260,6 +2260,23 @@ is disallowed in general).
Support for constant expression evaluation for the above builtins be detected
with ``__has_feature(cxx_constexpr_string_builtins)``.

Memory builtins
---------------

 * ``__builtin_memcpy_inline``

.. code-block:: c

  void __builtin_memcpy_inline(void *dst, const void *src, size_t size);

``__builtin_memcpy_inline(dst, src, size)`` is identical to
``__builtin_memcpy(dst, src, size)`` except that the generated code is
guaranteed not to call any external functions. See [LLVM IR ‘llvm.memcpy.inline’
Intrinsic](https://llvm.org/docs/LangRef.html#llvm-memcpy-inline-intrinsic) for
more information.

Note that the `size` argument must be a compile time constant.

Atomic Min/Max builtins with memory ordering
--------------------------------------------

+1 −0
Original line number Diff line number Diff line
@@ -480,6 +480,7 @@ BUILTIN(__builtin_fprintf, "iP*cC*.", "Fp:1:")
BUILTIN(__builtin_memchr, "v*vC*iz", "nF")
BUILTIN(__builtin_memcmp, "ivC*vC*z", "nF")
BUILTIN(__builtin_memcpy, "v*v*vC*z", "nF")
BUILTIN(__builtin_memcpy_inline, "vv*vC*Iz", "nt")
BUILTIN(__builtin_memmove, "v*v*vC*z", "nF")
BUILTIN(__builtin_mempcpy, "v*v*vC*z", "nF")
BUILTIN(__builtin_memset, "v*v*iz", "nF")
+7 −0
Original line number Diff line number Diff line
@@ -280,6 +280,13 @@ public:
                        IsVolatile);
  }

  using CGBuilderBaseTy::CreateMemCpyInline;
  llvm::CallInst *CreateMemCpyInline(Address Dest, Address Src, uint64_t Size) {
    return CreateMemCpyInline(
        Dest.getPointer(), Dest.getAlignment().getAsAlign(), Src.getPointer(),
        Src.getAlignment().getAsAlign(), getInt64(Size));
  }

  using CGBuilderBaseTy::CreateMemMove;
  llvm::CallInst *CreateMemMove(Address Dest, Address Src, llvm::Value *Size,
                                bool IsVolatile = false) {
+13 −0
Original line number Diff line number Diff line
@@ -2518,6 +2518,19 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID,
      return RValue::get(Dest.getPointer());
  }
  case Builtin::BI__builtin_memcpy_inline: {
    Address Dest = EmitPointerWithAlignment(E->getArg(0));
    Address Src = EmitPointerWithAlignment(E->getArg(1));
    uint64_t Size =
        E->getArg(2)->EvaluateKnownConstInt(getContext()).getZExtValue();
    EmitNonNullArgCheck(RValue::get(Dest.getPointer()), E->getArg(0)->getType(),
                        E->getArg(0)->getExprLoc(), FD, 0);
    EmitNonNullArgCheck(RValue::get(Src.getPointer()), E->getArg(1)->getType(),
                        E->getArg(1)->getExprLoc(), FD, 1);
    Builder.CreateMemCpyInline(Dest, Src, Size);
    return RValue::get(nullptr);
  }
  case Builtin::BI__builtin_char_memchr:
    BuiltinID = Builtin::BI__builtin_memchr;
    break;
+11 −0
Original line number Diff line number Diff line
@@ -1376,6 +1376,9 @@ CheckBuiltinTargetSupport(Sema &S, unsigned BuiltinID, CallExpr *TheCall,
  return true;
}
static void CheckNonNullArgument(Sema &S, const Expr *ArgExpr,
                                 SourceLocation CallSiteLoc);
ExprResult
Sema::CheckBuiltinFunctionCall(FunctionDecl *FDecl, unsigned BuiltinID,
                               CallExpr *TheCall) {
@@ -1645,6 +1648,14 @@ Sema::CheckBuiltinFunctionCall(FunctionDecl *FDecl, unsigned BuiltinID,
  case Builtin::BI__builtin_nontemporal_load:
  case Builtin::BI__builtin_nontemporal_store:
    return SemaBuiltinNontemporalOverloaded(TheCallResult);
  case Builtin::BI__builtin_memcpy_inline: {
    // __builtin_memcpy_inline size argument is a constant by definition.
    if (TheCall->getArg(2)->EvaluateKnownConstInt(Context).isNullValue())
      break;
    CheckNonNullArgument(*this, TheCall->getArg(0), TheCall->getExprLoc());
    CheckNonNullArgument(*this, TheCall->getArg(1), TheCall->getExprLoc());
    break;
  }
#define BUILTIN(ID, TYPE, ATTRS)
#define ATOMIC_BUILTIN(ID, TYPE, ATTRS) \
  case Builtin::BI##ID: \
Loading