Skip to content

[LangRef/DataLayout] Spell out requirements for alignment values #104705

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
Apr 6, 2025

Conversation

s-barannikov
Copy link
Contributor

@s-barannikov s-barannikov commented Aug 18, 2024

For 'p' the added wording matches the implementation.

For 'i', 'f', 'v' the implementation also allows 0 for <pref> component, making 'i16:16:0' valid, for example. 'Fi0', 'Fn0' and 'S0' are also currently accepted. This is likely unintentional. There are no tests in the codebase that rely on this behavior, so the added wording prohibits zero alignments for these specifications.

For 'a', the implementation currently allows 0 for both <abi> and <pref> components. The added wording prohibits specifying zero for <pref> with the same justification as above. Zero <abi> is used in tests, and the example at the end of the section suggests that this is valid, so that's left unchanged.

This effectively prohibits zero alignments everywhere except for the <abi> component of aggregate specification.

For 'p' the added wording matches the implementation.

For 'i', 'f', 'v' the implementation also allows 0 for <pref> component,
making 'i16:16:0' valid, for example. 'Fi0', 'Fn0' and 'S0' are also
currently accepted. This is likely unintentional. There are no tests
in the codebase that rely on this behavior, so the added wording
prohibits zero alignments for these specifications.

For 'a', the implementation currently allows 0 for both <abi> and <pref>
components. The added wording prohibits specifying zero for <pref>
with the same justification as above. Zero <abi> is used in tests,
and the example at the end of the section suggests that this is valid,
so that is left unchanged.

This effectively prohibits zero alignments everywhere except for
the <abi> component of aggregate specification.
@s-barannikov s-barannikov requested a review from nikic August 18, 2024 13:30
@llvmbot
Copy link
Member

llvmbot commented Aug 18, 2024

@llvm/pr-subscribers-llvm-ir

Author: Sergei Barannikov (s-barannikov)

Changes

For 'p' the added wording matches the implementation.

For 'i', 'f', 'v' the implementation also allows 0 for <pref> component, making 'i16:16:0' valid, for example. 'Fi0', 'Fn0' and 'S0' are also currently accepted. This is likely unintentional. There are no tests in the codebase that rely on this behavior, so the added wording prohibits zero alignments for these specifications.

For 'a', the implementation currently allows 0 for both <abi> and <pref> components. The added wording prohibits specifying zero for <pref> with the same justification as above. Zero <abi> is used in tests, and the example at the end of the section suggests that this is valid, so that's left unchanged.

This effectively prohibits zero alignments everywhere except for the <abi> component of aggregate specification.


Full diff: https://github.com/llvm/llvm-project/pull/104705.diff

1 Files Affected:

  • (modified) llvm/docs/LangRef.rst (+17-2)
diff --git a/llvm/docs/LangRef.rst b/llvm/docs/LangRef.rst
index 5e5e9b9e8a93b1..ea4fb6030161aa 100644
--- a/llvm/docs/LangRef.rst
+++ b/llvm/docs/LangRef.rst
@@ -3030,8 +3030,10 @@ as follows:
 ``S<size>``
     Specifies the natural alignment of the stack in bits. Alignment
     promotion of stack variables is limited to the natural stack
-    alignment to avoid dynamic stack realignment. The stack alignment
-    must be a multiple of 8-bits. If omitted, the natural stack
+    alignment to avoid dynamic stack realignment.
+    The stack alignment must be must be in the range [1,2^16)
+    and must be a power of two times the byte width.
+    If omitted, the natural stack
     alignment defaults to "unspecified", which does not prevent any
     alignment promotions.
 ``P<address space>``
@@ -3065,16 +3067,22 @@ as follows:
     are in bits. The address space, ``n``, is optional, and if not specified,
     denotes the default address space 0. The value of ``n`` must be
     in the range [1,2^24).
+    The values of ``<abi>`` and ``<pref>`` must be in the range [1,2^16)
+    and must be powers of two times the byte width.
 ``i<size>:<abi>[:<pref>]``
     This specifies the alignment for an integer type of a given bit
     ``<size>``. The value of ``<size>`` must be in the range [1,2^24).
     ``<pref>`` is optional and defaults to ``<abi>``.
+    The values of ``<abi>`` and ``<pref>`` must be in the range [1,2^16)
+    and must be powers of two times the byte width.
     For ``i8``, the ``<abi>`` value must equal 8,
     that is, ``i8`` must be naturally aligned.
 ``v<size>:<abi>[:<pref>]``
     This specifies the alignment for a vector type of a given bit
     ``<size>``. The value of ``<size>`` must be in the range [1,2^24).
     ``<pref>`` is optional and defaults to ``<abi>``.
+    The values of ``<abi>`` and ``<pref>`` must be in the range [1,2^16)
+    and must be powers of two times the byte width.
 ``f<size>:<abi>[:<pref>]``
     This specifies the alignment for a floating-point type of a given bit
     ``<size>``. Only values of ``<size>`` that are supported by the target
@@ -3082,9 +3090,14 @@ as follows:
     or 128 (different flavors of long double) are also supported on some
     targets. The value of ``<size>`` must be in the range [1,2^24).
     ``<pref>`` is optional and defaults to ``<abi>``.
+    The values of ``<abi>`` and ``<pref>`` must be in the range [1,2^16)
+    and must be powers of two times the byte width.
 ``a:<abi>[:<pref>]``
     This specifies the alignment for an object of aggregate type.
     ``<pref>`` is optional and defaults to ``<abi>``.
+    The values of ``<abi>`` and ``<pref>`` must be in the range [1,2^16)
+    and must be powers of two times the byte width.
+    The value of ``<<abi>>` may also be zero meaning one byte alignment.
 ``F<type><abi>``
     This specifies the alignment for function pointers.
     The options for ``<type>`` are:
@@ -3093,6 +3106,8 @@ as follows:
       of functions, and is a multiple of ``<abi>``.
     * ``n``: The alignment of function pointers is a multiple of the explicit
       alignment specified on the function, and is a multiple of ``<abi>``.
+    The values of ``<abi>`` and ``<pref>`` must be in the range [1,2^16)
+    and must be powers of two times the byte width.
 ``m:<mangling>``
     If present, specifies that llvm names are mangled in the output. Symbols
     prefixed with the mangling escape character ``\01`` are passed through

must be a multiple of 8-bits. If omitted, the natural stack
alignment to avoid dynamic stack realignment.
The stack alignment must be must be in the range [1,2^16)
and must be a power of two times the byte width.
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not very happy with this wording.
What I'm trying to say is that the value must be ByteWidth * 2^N ,without assuming that ByteWidth == 8.

@s-barannikov
Copy link
Contributor Author

I don't know who else I should add as reviewers.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we say once at the top that all alignment specs must be powers of two etc, rather than repeating it for each use?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I did that because size and address spaces requirements are repeated too, but I don't feel like I should be moving them in this PR. (Or should I?)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've moved the repeated sentences to the bottom, next to the other text that talks about alignments.

@@ -3030,8 +3030,7 @@ as follows:
``S<size>``
Specifies the natural alignment of the stack in bits. Alignment
promotion of stack variables is limited to the natural stack
alignment to avoid dynamic stack realignment. The stack alignment
must be a multiple of 8-bits. If omitted, the natural stack

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please do not delete the 8-bits!!!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is implied in the added paragraph.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is an 8-bit per byte world and your downstream target differs from that assumption. Don't play games.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please be constructive in your criticism.
I'm marking this conversation as resolved unless you have any specific concerns.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not resolved. You substitute 8-bit by byte to remove the 8-bit restriction.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

constructive criticism?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

cheap trick

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it's fine omit the 8-bit mention here. It's only mentioned once for S and not any of the other alignment specifications. I looked through LangRef a bit, and with the notable exception of this sentence, the wording always tries to be byte-size agnostic.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LangRef probably should mention somewhere that bytes are 8 bits large in LLVM -- this just isn't the right place, as it's a global assumption, not specific to only this one thing.

Not sure it makes sense to actually add that note now though, if there are plans to lift this restriction in the near future.

@tschuett
Copy link

@nikic feature request: bytes are 8-bit.

Copy link

@tschuett tschuett left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

restore the 8-bit restriction

@nikic
Copy link
Contributor

nikic commented Aug 20, 2024

For 'a', the implementation currently allows 0 for both <abi> and <pref> components. The added wording prohibits specifying zero for <pref> with the same justification as above. Zero <abi> is used in tests, and the example at the end of the section suggests that this is valid, so that's left unchanged.

Looks like the data layouts emitted by clang even use a:0, so yeah, it doesn't look like we can change that part without more effort than it is worth...

@@ -3123,6 +3120,9 @@ as follows:
as :ref:`Non-Integral Pointer Type <nointptrtype>` s. The ``0``
address space cannot be specified as non-integral.

Unless explicitly stated otherwise, on every specification that specifies
an alignment, the value of the alignment must be in the range [1,2^16)
and must be a power of two times the width of a byte.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
and must be a power of two times the width of a byte.
and must be a power of two greater than the width of a byte.

Would be slightly clearer imho -- but preclude non-power-of-two bytes. Was potentially allowing those in the future the motivation for the chosen wording?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm only considering supporting 16-bit bytes as the most popular, and 32-bit as that is the width of a byte on my architecture.
For these cases either of the following will do:

  1. "must be a power of two and a multiple of the byte width"
  2. "must be a power of two and at least the width of a byte"

The suggested "must be a power of two times the width of a byte" is more relaxed as it allows any byte width, e.g., 24, so that 24-, 48- and 96-bit alignments are valid (1, 2 and 4 bytes, respectively) even though the values are not powers of two. I'm not pursuing this generalization; the idea was that if it's equally easy to read, why not allow it. (I don't find it easy to read at all, but I can only judge this by my limited English.)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay, let's stick with your current wording :)

Copy link
Contributor

@nikic nikic left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@s-barannikov
Copy link
Contributor Author

@nikic Are you still ok with this change?

@s-barannikov s-barannikov requested a review from nikic April 6, 2025 16:23
@s-barannikov s-barannikov merged commit eb70253 into llvm:main Apr 6, 2025
10 checks passed
@s-barannikov s-barannikov deleted the datalayout/langref-alignments branch April 6, 2025 17:08
@llvm-ci
Copy link
Collaborator

llvm-ci commented Apr 6, 2025

LLVM Buildbot has detected a new failure on builder clang-aarch64-sve2-vla-2stage running on linaro-g4-02 while building llvm at step 12 "ninja check 2".

Full details are available at: https://lab.llvm.org/buildbot/#/builders/199/builds/2625

Here is the relevant piece of the build log for the reference
Step 12 (ninja check 2) failure: stage 2 checked (failure)
...
PASS: Flang :: Driver/linker-flags.f90 (24781 of 96621)
PASS: Flang :: Driver/macro-def-undef.F90 (24782 of 96621)
PASS: Flang :: Driver/override-triple.ll (24783 of 96621)
PASS: Flang :: Driver/include-header.f90 (24784 of 96621)
PASS: Flang :: Driver/predefined-macros-compiler-version.F90 (24785 of 96621)
PASS: Flang :: Driver/print-resource-dir.F90 (24786 of 96621)
PASS: Flang :: Driver/lto-bc.f90 (24787 of 96621)
PASS: Flang :: Driver/parse-fir-error.ll (24788 of 96621)
PASS: Flang :: Driver/phases.f90 (24789 of 96621)
UNRESOLVED: Flang :: Driver/slp-vectorize.ll (24790 of 96621)
******************** TEST 'Flang :: Driver/slp-vectorize.ll' FAILED ********************
Test has no 'RUN:' line
********************
PASS: Flang :: Driver/parse-error.ll (24791 of 96621)
PASS: Flang :: Driver/print-pipeline-passes.f90 (24792 of 96621)
PASS: Flang :: Driver/fixed-line-length.f90 (24793 of 96621)
PASS: Flang :: Driver/mlir-pass-pipeline.f90 (24794 of 96621)
PASS: Flang :: Driver/print-target-triple.f90 (24795 of 96621)
PASS: Flang :: Driver/scanning-error.f95 (24796 of 96621)
PASS: Flang :: Driver/parse-ir-error.f95 (24797 of 96621)
PASS: Flang :: Driver/pthread.f90 (24798 of 96621)
PASS: Flang :: Driver/pass-plugin-not-found.f90 (24799 of 96621)
PASS: Clangd Unit Tests :: ./ClangdTests/73/81 (24800 of 96621)
PASS: Flang :: Driver/std2018-wrong.f90 (24801 of 96621)
PASS: Flang :: Driver/supported-suffices/f03-suffix.f03 (24802 of 96621)
PASS: Flang :: Driver/mlink-builtin-bc.f90 (24803 of 96621)
PASS: Flang :: Driver/pp-fixed-form.f90 (24804 of 96621)
PASS: Flang :: Driver/fsave-optimization-record.f90 (24805 of 96621)
PASS: Flang :: Driver/supported-suffices/f08-suffix.f08 (24806 of 96621)
PASS: Flang :: Driver/tco-code-gen-llvm.fir (24807 of 96621)
PASS: Flang :: Driver/target-gpu-features.f90 (24808 of 96621)
PASS: Flang :: Driver/missing-arg.f90 (24809 of 96621)
PASS: Flang :: Driver/target.f90 (24810 of 96621)
PASS: Flang :: Driver/q-unused-arguments.f90 (24811 of 96621)
PASS: Flang :: Driver/lto-flags.f90 (24812 of 96621)
PASS: Flang :: Driver/multiple-input-files.f90 (24813 of 96621)
PASS: Flang :: Driver/unsupported-vscale-max-min.f90 (24814 of 96621)
PASS: Flang :: Driver/mllvm.f90 (24815 of 96621)
PASS: Flang :: Driver/input-from-stdin/input-from-stdin.f90 (24816 of 96621)
PASS: Flang :: Driver/unparse-with-modules.f90 (24817 of 96621)
PASS: Flang :: Driver/target-machine-error.f90 (24818 of 96621)
PASS: Flang :: Driver/prescanner-diag.f90 (24819 of 96621)
PASS: Flang :: Driver/unparse-use-analyzed.f95 (24820 of 96621)
PASS: Flang :: Driver/std2018.f90 (24821 of 96621)
PASS: Flang :: Driver/falias-analysis.f90 (24822 of 96621)
PASS: Flang :: Driver/no-duplicate-main.f90 (24823 of 96621)
PASS: Flang :: Driver/optimization-remark-backend.f90 (24824 of 96621)
PASS: Flang :: Driver/optimization-remark-invalid.f90 (24825 of 96621)
PASS: Flang :: Driver/save-temps-use-module.f90 (24826 of 96621)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants