| Issue |
179952
|
| Summary |
[CIR] RFC: Re-using existing AArch64 builtin tests for CIR
|
| Labels |
new issue
|
| Assignees |
|
| Reporter |
banach-space
|
Hi folks,
Some of you may be aware that I have recently started upstreaming / adding support for **AArch64 builtins** in **Clang via CIR**. I would like to use this ticket to start a discussion about the **long-term testing strategy**, and to propose a concrete approach for moving forward.
---
### Problem statement
There are currently **674** test files covering **AArch64 builtins** under:
```bash
clang/test/CodeGen/AArch64
```
This raises the question: **Should we re-use the existing AArch64 builtin tests for CIR?**
<details>
<summary>Expand for a full test file count ... </summary>
```bash
$ find clang/test/CodeGen/AArch64/ -type f \( -name '*.cpp' -o -name '*.h' -o -name '*.c' \) -print | cloc --list-file=-
674 text files.
674 unique files.
0 files ignored.
github.com/AlDanial/cloc v 2.08 T=0.63 s (1070.6 files/s, 433245.9 lines/s)
-------------------------------------------------------------------------------
Language files blank comment code
-------------------------------------------------------------------------------
C 667 17704 195861 57634
C++ 7 142 996 409
-------------------------------------------------------------------------------
SUM: 674 17846 196857 58043
-------------------------------------------------------------------------------
```
</details>
---
### Proposed solution
Where feasible - i.e. **when the difference between**:
* `clang -cc1 -emit-llvm file.c`, and
* `clang -cc1 -emit-llvm -fclangir file.c`
is negligible, non-existent or irrelevant, I propose that we **re-use the existing tests** rather than duplicating them.
In other words:
* If LLVM IR output is identical with and without CIR, the same test should validate both.
* CIR-specific validation should be added alongside, rather than living in a separate test file.
---
### Practicalities + Example
At a high level, this approach implies two changes:
* **Duplicate existing** `RUN` **lines** with `-fclangir` where LLVM IR is expected to match.
* **Add an additional** `RUN` **line** using `-emit-cir`, together with CIR-specific checks.
Below is a simplified example (adapted from #179779) to illustrate the idea.
<details>
<summary>BEFORE</summary>
```cpp
// REQUIRES: aarch64-registered-target || arm-registered-target
// RUN: %clang_cc1 ... -emit-llvm -o - %s | FileCheck %s --check-prefixes=ALL,LLVM
#include <arm_neon.h>
// LLVM-LABEL: @test_vceqzd_s64
uint64_t test_vceqzd_s64(int64_t a) {
// LLVM-SAME: i64{{.*}} [[A:%.*]])
// LLVM: [[TMP0:%.*]] = icmp eq i64 [[A]], 0
// LLVM-NEXT: [[VCEQZ_I:%.*]] = sext i1 [[TMP0]] to i64
// LLVM-NEXT: ret i64 [[VCEQZ_I]]
return (uint64_t)vceqzd_s64(a);
}
```
</details>
<details>
<summary>AFTER</summary>
```cpp
// REQUIRES: aarch64-registered-target || arm-registered-target
// RUN: %clang_cc1 ... -emit-llvm -o - %s | FileCheck %s --check-prefixes=ALL,LLVM
// RUN: %if cir-enabled %{%clang_cc1 ... -fclangir -emit-llvm -o - %s | FileCheck %s --check-prefixes=ALL,LLVM %}
// RUN: %if cir-enabled %{%clang_cc1 ... -fclangir -emit-cir -o - %s | FileCheck %s --check-prefixes=ALL,CIR %}
#include <arm_neon.h>
// ALL-LABEL: @test_vceqzd_s64
uint64_t test_vceqzd_s64(int64_t a) {
// CIR: [[C_0:%.*]] = cir.const #cir.int<0>
// CIR: [[CMP:%.*]] = cir.cmp(eq, %{{.*}}, [[C_0]]) : !s64i, !cir.bool
// CIR: [[RES:%.*]] = cir.cast bool_to_int [[CMP]] : !cir.bool -> !cir.int<s, 1>
// CIR: cir.cast integral [[RES]] : !cir.int<s, 1> -> !u64i
// LLVM-SAME: i64{{.*}} [[A:%.*]])
// LLVM: [[TMP0:%.*]] = icmp eq i64 [[A]], 0
// LLVM-NEXT: [[VCEQZ_I:%.*]] = sext i1 [[TMP0]] to i64
// LLVM-NEXT: ret i64 [[VCEQZ_I]]
return (uint64_t)vceqzd_s64(a);
}
```
</details>
---
### FileCheck prefixes
If we re-use tests from directories such as:
```bash
llvm-project/clang/test/CodeGen/AArch64
```
I would like to revisit the current use of the `OGCG` prefix for CIR (see e.g. [example](https://github.com/llvm/llvm-project/blob/02804501af9c764126964a965c02dbee84690227/clang/test/CIR/CodeGenBuiltins/builtin-fcmp-sse.c?plain=1#L5-L6)). From the perspective of contributors **not actively working on CIR**, `OGCG` (instead of something explicitly mentioning `LLVM` or `CIR`) feels unintuitive and harder to reason about.
I propose the following prefixes for tests outside clang/test/CIR:
| FileCheck Prefix | `RUN `Command(s) | Comments |
|-----------------|--------------------------------------------------|----------|
| LLVM | `clang -cc1 -emit-llvm`<br>`clang -cc1 -emit-llvm -fclangir` | For LLVM IR output that is identical _with_ and _without_ CIR |
| CIR | `clang -cc1 -emit-cir -fclangir` | For CIR output |
| LLVM-DEFAULT | `clang -cc1 -emit-llvm` | For LLVM IR output that only matches _without_ `-fclangir` |
| LLVM-VIA-CIR | `clang -cc1 -emit-llvm -fclangir` | For LLVM IR output that only matches _with_ `-fclangir` |
---
### Downsides
The main downside of this approach is **inconsistency with existing CIR tests**, including current tests for x86 builtins, which live under clang/test/CIR.
Personally, I feel that **consistency within a backend** (e.g. AArch64) is more important than strict consistency across all CIR tests, but this is very much open for discussion.
---
### Long-term steps
While my current focus is AArch64 builtins, I see test re-use as a **broader Clang-wide question**. If this approach works well here, it may motivate further consolidation and re-use in other areas over time.
---
Thanks for taking a look - I’m very interested in feedback on both the direction and the practical details of this proposal. And please let me know if I am missing anything!
-Andrzej
_______________________________________________
llvm-bugs mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs