From d33ae388aed4e5637dc1d1fa092db4d1e0a1a26d Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Tue, 7 Jan 2025 14:16:22 +0100 Subject: [PATCH 1/2] [LangRef] Add some documentation for ABI / call-site attributes Explicitly mention that attributes can be applied to call-sites, and explain that ABI attributes between the call-site and called function should match. Inspired by: https://discourse.llvm.org/t/difference-between-call-site-attributes-and-declaration-attributes/83902 --- llvm/docs/LangRef.rst | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/llvm/docs/LangRef.rst b/llvm/docs/LangRef.rst index 7e01331b20c57..64a91c6515ae7 100644 --- a/llvm/docs/LangRef.rst +++ b/llvm/docs/LangRef.rst @@ -1160,7 +1160,8 @@ The return type and each parameter of a function type may have a set of used to communicate additional information about the result or parameters of a function. Parameter attributes are considered to be part of the function, not of the function type, so functions with different -parameter attributes can have the same function type. +parameter attributes can have the same function type. Parameter attributes can +be placed both on function declarations/definitions, and at call-sites. Parameter attributes are either simple keywords or strings that follow the specified type. Multiple parameter attributes, when required, are separated by @@ -1168,14 +1169,31 @@ spaces. For example: .. code-block:: llvm + ; On function declarations/definitions: declare i32 @printf(ptr noalias nocapture, ...) declare i32 @atoi(i8 zeroext) declare signext i8 @returns_signed_char() define void @baz(i32 "amdgpu-flat-work-group-size"="1,256" %x) + ; On call-sites: + call i32 @atoi(i8 zeroext %x) + call signext i8 @returns_signed_char() + Note that any attributes for the function result (``nonnull``, ``signext``) come before the result type. +Parameter attributes can be broadly separated into two kinds: ABI attributes +that affect how values are passed to/from functions, like ``zeroext``, +``inreg``, ``byval``, or ``sret``. And optimization attributes, which provide +additional optimization guarantees, like ``noalias``, ``nonnull`` and +``dereferenceable``. + +ABI attributes must be specified *both* at the function declaration/definition +and call-site, otherwise the behavior may be undefined. ABI attributes cannot +be safely dropped. Optimization attributes do not have to match between +call-site and function: The intersection of their implied semantics applies. +Optimization attributes can also be freely dropped. + If an integer argument to a function is not marked signext/zeroext/noext, the kind of extension used is target-specific. Some targets depend for correctness on the kind of extension to be explicitly specified. From cc01ca760a4b0d5acef39b925d8fcd8eb972dd32 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Wed, 8 Jan 2025 09:46:25 +0100 Subject: [PATCH 2/2] Add note about noundef --- llvm/docs/LangRef.rst | 3 +++ 1 file changed, 3 insertions(+) diff --git a/llvm/docs/LangRef.rst b/llvm/docs/LangRef.rst index 64a91c6515ae7..4ee340c9a0315 100644 --- a/llvm/docs/LangRef.rst +++ b/llvm/docs/LangRef.rst @@ -1518,6 +1518,9 @@ Currently, only the following parameter attributes are defined: undefined. Note that this does not refer to padding introduced by the type's storage representation. + If memory sanitizer is enabled, ``noundef`` becomes an ABI attribute and + must match between the call-site and the function definition. + .. _nofpclass: ``nofpclass()``