Skip to content

Commit a5964ca

Browse files
authored
[Hexagon] Add coverage tests for CodeGen passes (#183951)
Add tests targeting specific Hexagon CodeGen passes with low coverage: - peephole-sxtw-combine.mir: HexagonPeephole pass exercising SXTW removal, combine generation, and LSR copy patterns. Improves HexagonPeephole.cpp line coverage from 63.89% to 99.31%. - vec-print-wq.ll: HexagonVectorPrint pass with V (single vector) and W (double vector) register printing via 128b HVX. Improves HexagonVectorPrint.cpp line coverage from 71.19% to 87.29%. - tfr-cleanup-double-imm.mir: HexagonTfrCleanup pass exercising 64-bit immediate rewrite paths. Improves HexagonTfrCleanup.cpp line coverage from 80.85% to 88.30%. - cfgopt-newpt-invert.ll: HexagonCFGOptimizer pass exercising branch inversion with new-value predicate transfers.
1 parent 2e10b62 commit a5964ca

File tree

4 files changed

+215
-0
lines changed

4 files changed

+215
-0
lines changed
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
; RUN: llc -mtriple=hexagon -hexagon-initial-cfg-cleanup=0 -O2 < %s \
2+
; RUN: | FileCheck %s
3+
4+
; Test coverage for HexagonCFGOptimizer: exercise the J2_jumptnewpt/J2_jumpfnewpt
5+
; branch inversion path. The CFG optimizer should invert a conditional branch
6+
; to eliminate an unconditional jump block.
7+
8+
; CHECK-LABEL: test_cfgopt_newpt:
9+
; CHECK: if ({{!?}}p0
10+
define i32 @test_cfgopt_newpt(i32 %a, i32 %b, i32 %c) #0 {
11+
entry:
12+
%cmp = icmp sgt i32 %a, %b
13+
br i1 %cmp, label %if.then, label %if.else
14+
15+
if.then:
16+
%add = add nsw i32 %a, %c
17+
br label %return
18+
19+
if.else:
20+
%sub = sub nsw i32 %b, %c
21+
%mul = mul nsw i32 %sub, 3
22+
br label %return
23+
24+
return:
25+
%retval = phi i32 [ %add, %if.then ], [ %mul, %if.else ]
26+
ret i32 %retval
27+
}
28+
29+
; Exercise the case2 path of CFG optimizer where JumpAroundTarget has a single
30+
; predecessor and a single successor with an unconditional jump.
31+
; CHECK-LABEL: test_cfgopt_case2:
32+
; CHECK: if ({{!?}}p0
33+
define i32 @test_cfgopt_case2(i32 %a, i32 %b, ptr %p) #0 {
34+
entry:
35+
%cmp = icmp eq i32 %a, 0
36+
br i1 %cmp, label %if.then, label %if.else
37+
38+
if.then:
39+
store i32 %b, ptr %p, align 4
40+
br label %merge
41+
42+
if.else:
43+
%add = add i32 %a, %b
44+
store i32 %add, ptr %p, align 4
45+
br label %merge
46+
47+
merge:
48+
%val = load i32, ptr %p, align 4
49+
ret i32 %val
50+
}
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
# RUN: llc -mtriple=hexagon -run-pass hexagon-peephole \
2+
# RUN: -disable-hexagon-optszext=false \
3+
# RUN: -disable-hexagon-opt-ext-to-64=false -o - %s | FileCheck %s
4+
5+
# Test coverage for HexagonPeephole:
6+
# 1) SXTW + COPY isub_lo optimization
7+
# 2) A4_combineir(0, r) + COPY isub_lo optimization
8+
# 3) S2_lsr_i_p(d, 32) + COPY isub_lo -> COPY isub_hi
9+
10+
--- |
11+
define void @test_sxtw_copy() { ret void }
12+
define void @test_combine_copy() { ret void }
13+
define void @test_lsr_copy() { ret void }
14+
...
15+
16+
---
17+
# SXTW + COPY isub_lo should be peepholed: the COPY should use the
18+
# original 32-bit source directly instead of extracting from the sxtw result.
19+
# CHECK-LABEL: name: test_sxtw_copy
20+
# CHECK: %2:intregs = COPY %0
21+
name: test_sxtw_copy
22+
tracksRegLiveness: true
23+
registers:
24+
- { id: 0, class: intregs }
25+
- { id: 1, class: doubleregs }
26+
- { id: 2, class: intregs }
27+
body: |
28+
bb.0:
29+
liveins: $r0
30+
%0:intregs = COPY $r0
31+
%1:doubleregs = A2_sxtw %0
32+
%2:intregs = COPY %1.isub_lo
33+
$r0 = COPY %2
34+
J2_jumpr $r31, implicit-def dead $pc, implicit killed $r0
35+
...
36+
37+
---
38+
# A4_combineir(0, r) + COPY isub_lo optimization: the COPY should use
39+
# the 32-bit source register directly.
40+
# CHECK-LABEL: name: test_combine_copy
41+
# CHECK: %2:intregs = COPY %0
42+
name: test_combine_copy
43+
tracksRegLiveness: true
44+
registers:
45+
- { id: 0, class: intregs }
46+
- { id: 1, class: doubleregs }
47+
- { id: 2, class: intregs }
48+
body: |
49+
bb.0:
50+
liveins: $r0
51+
%0:intregs = COPY $r0
52+
%1:doubleregs = A4_combineir 0, %0
53+
%2:intregs = COPY %1.isub_lo
54+
$r0 = COPY %2
55+
J2_jumpr $r31, implicit-def dead $pc, implicit killed $r0
56+
...
57+
58+
---
59+
# S2_lsr_i_p(d, 32) + COPY isub_lo should be transformed to
60+
# COPY isub_hi from the original double register.
61+
# CHECK-LABEL: name: test_lsr_copy
62+
# CHECK: %2:intregs = COPY %0.isub_hi
63+
name: test_lsr_copy
64+
tracksRegLiveness: true
65+
registers:
66+
- { id: 0, class: doubleregs }
67+
- { id: 1, class: doubleregs }
68+
- { id: 2, class: intregs }
69+
body: |
70+
bb.0:
71+
liveins: $d0
72+
%0:doubleregs = COPY $d0
73+
%1:doubleregs = S2_lsr_i_p %0, 32
74+
%2:intregs = COPY %1.isub_lo
75+
$r0 = COPY %2
76+
J2_jumpr $r31, implicit-def dead $pc, implicit killed $r0
77+
...
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
# RUN: llc -mtriple=hexagon -run-pass tfr-cleanup -o - %s | FileCheck %s
2+
3+
# Test coverage for HexagonTfrCleanup: exercise the 64-bit register
4+
# immediate rewrite paths including the A2_combineii case and the
5+
# A2_tfrpi case.
6+
7+
--- |
8+
define void @test_double_imm() { ret void }
9+
define void @test_combine_imm() { ret void }
10+
define void @test_self_copy() { ret void }
11+
...
12+
13+
---
14+
# Test: 64-bit register copy rewritten to A2_tfrpi when source holds
15+
# a small immediate (fits in int8).
16+
# CHECK-LABEL: name: test_double_imm
17+
# CHECK: A2_tfrpi
18+
name: test_double_imm
19+
tracksRegLiveness: true
20+
body: |
21+
bb.0:
22+
$r0 = A2_tfrsi 3
23+
$r1 = A2_tfrsi 0
24+
$d1 = A2_tfrp $d0
25+
...
26+
27+
---
28+
# Test: 64-bit register copy rewritten to A2_combineii when the source
29+
# value has both halves fitting in int8 but the full value does not.
30+
# CHECK-LABEL: name: test_combine_imm
31+
# CHECK: A2_combineii
32+
name: test_combine_imm
33+
tracksRegLiveness: true
34+
body: |
35+
bb.0:
36+
$r0 = A2_tfrsi 5
37+
$r1 = A2_tfrsi 7
38+
$d1 = A2_tfrp $d0
39+
...
40+
41+
---
42+
# Test: eraseIfRedundant - self-assignment A2_tfr should be removed.
43+
# CHECK-LABEL: name: test_self_copy
44+
# CHECK-NOT: A2_tfr $r0, $r0
45+
name: test_self_copy
46+
tracksRegLiveness: true
47+
body: |
48+
bb.0:
49+
liveins: $r0
50+
$r0 = A2_tfr $r0
51+
J2_jumpr $r31, implicit-def dead $pc
52+
...
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
; RUN: llc -mtriple=hexagon -mcpu=hexagonv68 -mattr=+hvxv68,+hvx-length128b \
2+
; RUN: -enable-hexagon-vector-print < %s | FileCheck %s
3+
4+
; Test coverage for HexagonVectorPrint: exercise the W (double vector)
5+
; and V (single vector) register printing paths.
6+
7+
; Use two stores so that the V result is not entirely consumed by a .new
8+
; store, leaving a live V register for the vector-print pass to instrument.
9+
; CHECK-LABEL: test_vecprint_v:
10+
; CHECK: InlineAsm Start
11+
; CHECK: .word
12+
; CHECK: InlineAsm End
13+
define void @test_vecprint_v(<32 x i32> %a, <32 x i32> %b, ptr %p, ptr %q) #0 {
14+
entry:
15+
%add = add <32 x i32> %a, %b
16+
store <32 x i32> %add, ptr %p, align 128
17+
store <32 x i32> %add, ptr %q, align 128
18+
ret void
19+
}
20+
21+
; The W register case should emit inline asm blocks for each V sub-register.
22+
; CHECK-LABEL: test_vecprint_w:
23+
; CHECK: InlineAsm Start
24+
; CHECK: .word
25+
; CHECK: InlineAsm End
26+
; CHECK: InlineAsm Start
27+
; CHECK: .word
28+
; CHECK: InlineAsm End
29+
define void @test_vecprint_w(<64 x i32> %a, <64 x i32> %b, ptr %p) #0 {
30+
entry:
31+
%add = add <64 x i32> %a, %b
32+
store <64 x i32> %add, ptr %p, align 128
33+
ret void
34+
}
35+
36+
attributes #0 = { nounwind }

0 commit comments

Comments
 (0)