Skip to content

Commit bf5c0bf

Browse files
committed
arcv: apex: Add LTO testsuite for APEX intrinsics.
This patch adds tests for LTO support of APEX intrinsics, including both positive and negative test cases. The testsuite validates that APEX intrinsics declared via #pragma intrinsic directives in different translation units are correctly serialized, merged, and made available during link-time optimization. Test coverage includes: 1. Conflict Detection Tests (arcv-apex-lto-err*): - Opcode mismatch detection across compilation units - Instruction name mismatch detection - Instruction format mismatch detection - Multiple simultaneous conflicts 2. Successful LTO Tests (arcv-apex-lto-test*): - Multiple instruction formats (XD, XS, XI, XC) across files - Partial overlap of intrinsics between translation units - Different pragma declaration orders All tests verify that: - APEX intrinsic calls survive LTO optimization - Correct .extInstruction directives are emitted - Proper assembly instructions are generated - Conflicting definitions produce appropriate diagnostics Signed-off-by: Luis Silva <[email protected]>
1 parent 7da93d4 commit bf5c0bf

17 files changed

+385
-8
lines changed

gcc/testsuite/gcc.target/riscv/apex/apex.exp

Lines changed: 40 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -14,27 +14,59 @@
1414
# along with GCC; see the file COPYING3. If not see
1515
# <http://www.gnu.org/licenses/>.
1616

17-
# GCC testsuite that uses the `dg.exp' driver.
17+
# GCC testsuite for RISC-V APEX intrinsics.
18+
# This file handles both regular single-file tests and multi-file LTO tests.
1819

1920
# Exit immediately if this isn't a RISC-V target.
2021
if ![istarget riscv*-*-*] then {
2122
return
2223
}
2324

24-
# Load support procs.
25+
# Load all required libraries.
2526
load_lib gcc-dg.exp
27+
load_lib standard.exp
28+
load_lib gcc.exp
29+
load_lib lto.exp
30+
load_lib scanltrans.exp
2631

2732
global DEFAULT_CFLAGS
2833
if ![info exists DEFAULT_CFLAGS] then {
2934
set DEFAULT_CFLAGS " -ansi -pedantic-errors"
3035
}
3136

32-
# Initialize `dg'.
37+
#
38+
# Run regular single-file tests
39+
#
3340
dg-init
3441

35-
# Main loop.
36-
dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.\[cS\]]] \
37-
"" $DEFAULT_CFLAGS
42+
set tests [lsort [glob -nocomplain $srcdir/$subdir/*.\[cS\]]]
43+
set non_lto_tests [list]
44+
foreach test $tests {
45+
if {![string match "*arcv-apex-lto-*" $test]} {
46+
lappend non_lto_tests $test
47+
}
48+
}
49+
50+
dg-runtest $non_lto_tests "" $DEFAULT_CFLAGS
3851

39-
# All done.
40-
dg-finish
52+
dg-finish
53+
54+
#
55+
# Run multi-file LTO tests (if LTO is supported)
56+
#
57+
if { [check_effective_target_lto] } {
58+
gcc_init
59+
lto_init no-mathlib
60+
61+
set sid "riscv_apex_lto"
62+
63+
foreach src [lsort [find $srcdir/$subdir arcv-apex-lto-*_0.c]] {
64+
if ![runtest_file_p $runtests $src] then {
65+
continue
66+
}
67+
68+
lto-execute $src $sid
69+
}
70+
71+
lto_finish
72+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
/* { dg-lto-do link } */
2+
/* { dg-lto-options { { -flto -O2 } } } */
3+
4+
int apex_conflict (int, int);
5+
#pragma intrinsic (apex_conflict, "conflict", 50, "XS")
6+
7+
extern int use_conflict (int, int);
8+
9+
int
10+
main (void)
11+
{
12+
return use_conflict (5, 10);
13+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
2+
int apex_conflict (int, int);
3+
#pragma intrinsic (apex_conflict, "conflict", 51, "XS") /* Different opcode: 51 vs 50 */
4+
5+
int
6+
use_conflict (int a, int b)
7+
{
8+
return apex_conflict (a, b);
9+
}
10+
11+
/* { dg-lto-warning "APEX builtin 'apex_conflict' already registered with different opcode: 0x32 vs 0x33" "" { target *-*-* } 2 } */
12+
/* { dg-lto-error "APEX builtin 'apex_conflict' has conflicting definitions across compilation units" "" { target *-*-* } 2 } */
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
/* Test LTO error detection for instruction name mismatch */
2+
/* { dg-lto-do link } */
3+
/* { dg-lto-options { { -flto -O2 } } } */
4+
5+
int apex_insn_mismatch (int, int);
6+
#pragma intrinsic (apex_insn_mismatch, "insn_a", 100, "XD")
7+
8+
extern int use_insn_mismatch (int, int);
9+
10+
int
11+
main (void)
12+
{
13+
return use_insn_mismatch (5, 10);
14+
}
15+
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
2+
int apex_insn_mismatch (int, int);
3+
#pragma intrinsic (apex_insn_mismatch, "insn_b", 100, "XD") /* Different instruction name */
4+
5+
int
6+
use_insn_mismatch (int a, int b)
7+
{
8+
return apex_insn_mismatch (a, b);
9+
}
10+
11+
/* { dg-lto-warning "APEX builtin 'apex_insn_mismatch' already registered with different instruction name: 'insn_a' vs 'insn_b'" "" { target *-*-* } 2 } */
12+
/* { dg-lto-error "APEX builtin 'apex_insn_mismatch' has conflicting definitions across compilation units" "" { target *-*-* } 2 } */
13+
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
/* Test LTO error detection for instruction format mismatch */
2+
/* { dg-lto-do link } */
3+
/* { dg-lto-options { { -flto -O2 } } } */
4+
5+
int apex_format_mismatch (int, int);
6+
#pragma intrinsic (apex_format_mismatch, "format_test", 20, "XS")
7+
8+
extern int use_format_mismatch (int);
9+
10+
int
11+
main (void)
12+
{
13+
return use_format_mismatch (5);
14+
}
15+
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
2+
int apex_format_mismatch (int, int);
3+
#pragma intrinsic (apex_format_mismatch, "format_test", 20, "XC") /* Different format: XC vs XS */
4+
5+
int
6+
use_format_mismatch (int a)
7+
{
8+
return apex_format_mismatch (a, 10);
9+
}
10+
11+
/* { dg-lto-warning "APEX builtin 'apex_format_mismatch' already registered with different instruction formats: 0xe2 vs 0xe8" "" { target *-*-* } 2 } */
12+
/* { dg-lto-error "APEX builtin 'apex_format_mismatch' has conflicting definitions across compilation units" "" { target *-*-* } 2 } */
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
/* Test LTO error detection for multiple mismatches */
2+
/* { dg-lto-do link } */
3+
/* { dg-lto-options { { -flto -O2 } } } */
4+
5+
int apex_multi_mismatch (int, int);
6+
#pragma intrinsic (apex_multi_mismatch, "insn_original", 20, "XD")
7+
8+
extern int use_multi_mismatch (int);
9+
10+
int
11+
main (void)
12+
{
13+
return use_multi_mismatch (5);
14+
}
15+
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
2+
int apex_multi_mismatch (int, int);
3+
#pragma intrinsic (apex_multi_mismatch, "insn_different", 21, "XS") /* All different */
4+
5+
int
6+
use_multi_mismatch (int a)
7+
{
8+
return apex_multi_mismatch (a, 10);
9+
}
10+
11+
/* { dg-lto-warning "APEX builtin 'apex_multi_mismatch' already registered with different instruction name: 'insn_original' vs 'insn_different'" "" { target *-*-* } 2 } */
12+
/* { dg-lto-warning "APEX builtin 'apex_multi_mismatch' already registered with different opcode: 0x14 vs 0x15" "" { target *-*-* } 2 } */
13+
/* { dg-lto-warning "APEX builtin 'apex_multi_mismatch' already registered with different instruction formats: 0xe1 vs 0xe2" "" { target *-*-* } 2 } */
14+
/* { dg-lto-error "APEX builtin 'apex_multi_mismatch' has conflicting definitions across compilation units" "" { target *-*-* } 2 } */
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
/* { dg-lto-do link } */
2+
/* { dg-lto-options { { -flto -O2 -fdump-tree-optimized -save-temps } } } */
3+
4+
int func_apex_xd (int, int);
5+
#pragma intrinsic (func_apex_xd, "insn_apex_xd", 50, "XD")
6+
7+
int func_apex_xs (int, int);
8+
#pragma intrinsic (func_apex_xs, "insn_apex_xs", 32, "XS")
9+
10+
int func_apex_xi (int);
11+
#pragma intrinsic (func_apex_xi, "insn_apex_xi", 20, "XI")
12+
13+
int func_apex_xc (int, int);
14+
#pragma intrinsic (func_apex_xc, "insn_apex_xc", 21, "XC")
15+
16+
extern int foo (int);
17+
18+
int
19+
main (void)
20+
{
21+
int x = func_apex_xd (1,2);
22+
int y = func_apex_xs (x, 3);
23+
int z = func_apex_xi (4);
24+
int w = func_apex_xc (y, 5);
25+
26+
return foo (y) + w + z;
27+
}
28+
29+
/* Verify that APEX intrinsic calls survive LTO optimization. */
30+
/* { dg-final { scan-ltrans-tree-dump "func_apex_xd" "optimized" } } */
31+
/* { dg-final { scan-ltrans-tree-dump "func_apex_xs" "optimized" } } */
32+
/* { dg-final { scan-ltrans-tree-dump "func_apex_xi" "optimized" } } */
33+
/* { dg-final { scan-ltrans-tree-dump "func_apex_xc" "optimized" } } */
34+
35+
/* Verify that the correct custom instructions are emitted in assembly. */
36+
/* { dg-final { scan-ltrans-assembler "\\.extInstruction insn_apex_xd,50,XD" } } */
37+
/* { dg-final { scan-ltrans-assembler "\\.extInstruction insn_apex_xs,32,XS" } } */
38+
/* { dg-final { scan-ltrans-assembler "\\.extInstruction insn_apex_xi,20,XI" } } */
39+
/* { dg-final { scan-ltrans-assembler "\\.extInstruction insn_apex_xc,21,XC" } } */
40+
41+
/* { dg-final { scan-ltrans-assembler-times "insn_apex_xd\\s+a\[0-9\]+,a\[0-9\]+,a\[0-9\]+" 2 } } */
42+
/* { dg-final { scan-ltrans-assembler-times "insn_apex_xs\\s+a\[0-9\]+,a\[0-9\]+,3" 1 } } */
43+
/* { dg-final { scan-ltrans-assembler-times "insn_apex_xi\\s+a\[0-9\]+,4" 1 } } */
44+
/* { dg-final { scan-ltrans-assembler-times "insn_apex_xc\\s+a\[0-9\]+,a\[0-9\]+,5" 1 } } */
45+
46+
/* { dg-final { scan-ltrans-assembler-times "insn_apex_xs\\s+a\[0-9\]+,a\[0-9\]+,8" 1 } } */
47+
/* { dg-final { scan-ltrans-assembler-times "insn_apex_xi\\s+a\[0-9\]+,9" 1 } } */
48+
/* { dg-final { scan-ltrans-assembler-times "insn_apex_xc\\s+a\[0-9\]+,a\[0-9\]+,10" 1 } } */
49+

0 commit comments

Comments
 (0)