ansi-c: declare ARM/AArch64 NEON builtins#9039
Draft
tautschnig wants to merge 7 commits into
Draft
Conversation
4 tasks
There was a problem hiding this comment.
Pull request overview
Note
Copilot was unable to run its full agentic suite in this review.
Adds support for parsing/declaring AArch64 NEON (__builtin_neon_*) builtins by introducing a new per-target GCC builtin header and wiring it into the ANSI-C front-end builtin lookup.
Changes:
- Add a generated
gcc_builtin_headers_aarch64.hand its corresponding.incintegration. - Extend builtin lookup to consult the AArch64 builtin header in the ARM-related path.
- Update Makefile/CMake to generate/ship the new
.incfile.
Reviewed changes
Copilot reviewed 6 out of 6 changed files in this pull request and generated 6 comments.
Show a summary per file
| File | Description |
|---|---|
| src/ansi-c/compiler_headers/gcc_builtin_headers_aarch64.h | New generated declarations for AArch64 NEON builtins |
| src/ansi-c/builtin_factory.cpp | Consult AArch64 builtin header during builtin resolution |
| src/ansi-c/ansi_c_internal_additions.h | Declare new builtin-header string symbol for AArch64 |
| src/ansi-c/ansi_c_internal_additions.cpp | Define builtin-header string for AArch64 and include generated .inc |
| src/ansi-c/Makefile | Add AArch64 .inc file to builtin generation list |
| src/ansi-c/CMakeLists.txt | Add AArch64 .inc generation and dependencies |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| float __builtin_neon_vabds_f32(float, float); | ||
| __gcc_v8qi __builtin_neon_vabs_f16(__gcc_v8qi, int); | ||
| __gcc_v8qi __builtin_neon_vabs_v(__gcc_v8qi, int); | ||
| int64_t int64_t __builtin_neon_vabsd_s64(void); |
Comment on lines
+23
to
+33
| int64_t int64_t int64_t __builtin_neon_vaddd_s64(void); | ||
| unsigned int64_t unsigned int64_t unsigned int64_t __builtin_neon_vaddd_u64(void); | ||
| __gcc_v8qi __builtin_neon_vaddhn_v(__gcc_v16qi, __gcc_v16qi, int); | ||
| int __builtin_neon_vaddlv_s16(__gcc_v4hi); | ||
| int64_t __gcc_v2si __builtin_neon_vaddlv_s32(void); | ||
| short __builtin_neon_vaddlv_s8(__gcc_v8qi); | ||
| int __builtin_neon_vaddlvq_s16(__gcc_v8hi); | ||
| int64_t __gcc_v4si __builtin_neon_vaddlvq_s32(void); | ||
| short __builtin_neon_vaddlvq_s8(__gcc_v16qi); | ||
| unsigned int __builtin_neon_vaddlvq_u16(__gcc_v8uhi); | ||
| unsigned int64_t __gcc_v4usi __builtin_neon_vaddlvq_u32(void); |
Comment on lines
+241
to
+244
| double __builtin_neon_vcvtd_n_f64_s64(int64_t int); | ||
| double __builtin_neon_vcvtd_n_f64_u64(unsigned int64_t int); | ||
| int64_t double __builtin_neon_vcvtd_n_s64_f64(int); | ||
| unsigned int64_t double __builtin_neon_vcvtd_n_u64_f64(int); |
Comment on lines
+733
to
+734
| int __builtin_neon_vqrshrnd_n_s64(int64_t int); | ||
| unsigned int __builtin_neon_vqrshrnd_n_u64(unsigned int64_t int); |
| __gcc_v16qi __builtin_neon_vldap1q_lane_p64(const void *, __gcc_v16qi, int, int); | ||
| __gcc_v16qi __builtin_neon_vldap1q_lane_s64(const void *, __gcc_v16qi, int, int); | ||
| __gcc_v16qi __builtin_neon_vldap1q_lane_u64(const void *, __gcc_v16qi, int, int); | ||
| const unsigned __int128_t void * __builtin_neon_vldrq_p128(void); |
Comment on lines
206
to
212
| { | ||
| if(find_pattern(pattern, gcc_builtin_headers_arm, s)) | ||
| return convert(identifier, s, symbol_table, mh); | ||
|
|
||
| if(find_pattern(pattern, gcc_builtin_headers_aarch64, s)) | ||
| return convert(identifier, s, symbol_table, mh); | ||
| } |
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## develop #9039 +/- ##
========================================
Coverage 80.68% 80.68%
========================================
Files 1713 1713
Lines 189499 189501 +2
Branches 73 73
========================================
+ Hits 152890 152894 +4
+ Misses 36609 36607 -2 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
ad215fc to
de7e805
Compare
As of LLVM 20 the per-target builtin databases were migrated from the X-macro ".def" files to TableGen ".td", and NEON/SVE builtins are emitted by clang-tblgen into a "..._BUILTIN_INFOS" form using the classic compact type encoding. Rewrite clang_builtins.py to parse the TableGen .td databases directly, and add a --inc PREFIX:PATH mode that parses clang-tblgen-generated .inc files (e.g. NEON from -gen-arm-neon-sema), prepending PREFIX to each spelling. Co-authored-by: Kiro <kiro-agent@users.noreply.github.com>
The compact-encoding decoder treated the width-modified integer types Wi
(64-bit), Zi (32-bit) and LLLi (128-bit) as non-terminating prefixes mapped to
int64_t/int32_t/__int128_t. As a result a following type was merged into the
same one (e.g. WiWi -> "int64_t int64_t" rather than a 64-bit return plus a
64-bit argument), and the unsigned forms produced invalid C ("unsigned
int64_t"). These show up in the ARM NEON scalar builtins (vabsd_s64,
vaddlvq_u32, vcvtd_n_u64_f64, vqrshrnd_n_u64, vaddq_p128, vmull_p64, ...).
Treat Wi/Zi/LLLi as complete types ("long long"/"int"/"__int128") that
terminate the prefix, with U/S applying as the sign, and alias the resulting
"long long" element to the existing vector typedef key so int64 vectors still
resolve. uint64x1 vectors remain skipped as CBMC has no __gcc_v1udi typedef.
Co-authored-by: Kiro <kiro-agent@users.noreply.github.com>
The TableGen .td walker and the compact-encoding decoder are the pieces most likely to break silently when LLVM changes its emitters, and nothing in CI exercises this maintainer script. Add a --self-test flag that round-trips a one-line X86Builtin def through process_td, checks a handful of decode_encoding cases (including the Wi/Zi/LLLi width-modified integer types and a half-float scalar), guards that a vector without a lane count is reported as unmappable rather than crashing, and runs process_inc on a one-entry BUILTIN_INFOS snippet. Co-authored-by: Kiro <kiro-agent@users.noreply.github.com>
Embed builtin headers as a C character-array initialiser ({ 'a', 'b', ..., 0 })
rather than a string literal. String literals are limited to 65536 characters
after concatenation -- a limit clang enforces under -pedantic -- which forced
large headers (e.g. the ia32 ones) to be split across several files; a
character array has no such limit. The #line directive that the use sites used
to prepend as a separate string literal is now baked into the array by
file_converter, so each use site is just `const char x[] = #include "x.inc";`.
This unblocks embedding arbitrarily large generated headers and lets the
artificially split headers be recombined (done separately).
Co-authored-by: Kiro <kiro-agent@users.noreply.github.com>
The ia32 GCC builtin declarations were split across nine headers (gcc_builtin_headers_ia32.h plus -2..-9) solely to keep each embedded string literal under the 65536-character limit. Now that file_converter emits a character-array initialiser with no such limit, fold them back into a single gcc_builtin_headers_ia32.h and drop the now-redundant per-file symbols, find_pattern lookups, and build rules. Co-authored-by: Kiro <kiro-agent@users.noreply.github.com>
Add gcc_builtin_headers_aarch64.h (Clang __builtin_neon_* declarations, generated by clang_builtins.py from clang-tblgen -gen-arm-neon-sema) and wire it into the front-end like the other per-target builtin headers: extern + string constant in ansi_c_internal_additions, a find_pattern() lookup in the ARM branch of builtin_factory, and the .inc generation rules in the Makefile and CMakeLists. The NEON builtins are polymorphic (arm_neon.h casts operands to the representative lane type and passes a NeonTypeFlags code), so each has a single concrete __gcc_v* signature. Co-authored-by: Kiro <kiro-agent@users.noreply.github.com>
Regenerate gcc_builtin_headers_aarch64.h with the corrected clang_builtins.py decoder: the width-modified integer encodings Wi/Zi/LLLi are now rendered as complete C types, fixing the malformed prototypes Copilot flagged (e.g. "int64_t int64_t __builtin_neon_vabsd_s64(void)" becomes "long long __builtin_neon_vabsd_s64(long long)"). The set otherwise tracks the LLVM version of the arm_neon.td used to regenerate it. Give arm64 (AArch64) its own arch branch in builtin_factory that searches only the AArch64 header: AArch64 has no 32-bit-only builtins, and searching the 32-bit ARM header first could let an ARM signature win for a NEON name shared by both architectures. Drop the "#line" string-literal prefix from the AArch64 header embedding: now that file_converter emits a character-array initialiser, the directive is baked into the array and a string-literal prefix can no longer be concatenated to it. Co-authored-by: Kiro <kiro-agent@users.noreply.github.com>
de7e805 to
618dd59
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Depends-on: #9041
Add gcc_builtin_headers_aarch64.h (Clang _builtin_neon* declarations, generated by clang_builtins.py from clang-tblgen -gen-arm-neon-sema) and wire it into the front-end like the other per-target builtin headers: extern + string constant in ansi_c_internal_additions, a find_pattern() lookup in the ARM branch of builtin_factory, and the .inc generation rules in the Makefile and CMakeLists. The NEON builtins are polymorphic (arm_neon.h casts operands to the representative lane type and passes a NeonTypeFlags code), so each has a single concrete __gcc_v* signature.