• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1; RUN: llc -debugify-and-strip-all-safe < %s -O3 -mtriple=aarch64-eabi -verify-machineinstrs | FileCheck %s
2
3target datalayout = "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128"
4target triple = "aarch64-linaro-linux-gnueabi"
5
6; CMN is an alias of ADDS.
7; CHECK-LABEL: test_add_cbz:
8; CHECK: cmn w0, w1
9; CHECK: b.eq
10; CHECK: ret
11define void @test_add_cbz(i32 %a, i32 %b, i32* %ptr) {
12  %c = add nsw i32 %a, %b
13  %d = icmp ne i32 %c, 0
14  br i1 %d, label %L1, label %L2
15L1:
16  store i32 0, i32* %ptr, align 4
17  ret void
18L2:
19  store i32 1, i32* %ptr, align 4
20  ret void
21}
22
23; CHECK-LABEL: test_add_cbz_multiple_use:
24; CHECK: adds
25; CHECK: b.eq
26; CHECK: ret
27define void @test_add_cbz_multiple_use(i32 %a, i32 %b, i32* %ptr) {
28  %c = add nsw i32 %a, %b
29  %d = icmp ne i32 %c, 0
30  br i1 %d, label %L1, label %L2
31L1:
32  store i32 0, i32* %ptr, align 4
33  ret void
34L2:
35  store i32 %c, i32* %ptr, align 4
36  ret void
37}
38
39; CHECK-LABEL: test_add_cbz_64:
40; CHECK: cmn x0, x1
41; CHECK: b.eq
42define void @test_add_cbz_64(i64 %a, i64 %b, i64* %ptr) {
43  %c = add nsw i64 %a, %b
44  %d = icmp ne i64 %c, 0
45  br i1 %d, label %L1, label %L2
46L1:
47  store i64 0, i64* %ptr, align 4
48  ret void
49L2:
50  store i64 1, i64* %ptr, align 4
51  ret void
52}
53
54; CHECK-LABEL: test_and_cbz:
55; CHECK: tst w0, #0x6
56; CHECK: b.eq
57define void @test_and_cbz(i32 %a, i32* %ptr) {
58  %c = and i32 %a, 6
59  %d = icmp ne i32 %c, 0
60  br i1 %d, label %L1, label %L2
61L1:
62  store i32 0, i32* %ptr, align 4
63  ret void
64L2:
65  store i32 1, i32* %ptr, align 4
66  ret void
67}
68
69; CHECK-LABEL: test_bic_cbnz:
70; CHECK: bics wzr, w1, w0
71; CHECK: b.ne
72define void @test_bic_cbnz(i32 %a, i32 %b, i32* %ptr) {
73  %c = and i32 %a, %b
74  %d = icmp eq i32 %c, %b
75  br i1 %d, label %L1, label %L2
76L1:
77  store i32 0, i32* %ptr, align 4
78  ret void
79L2:
80  store i32 1, i32* %ptr, align 4
81  ret void
82}
83
84; CHECK-LABEL: test_add_tbz:
85; CHECK: adds
86; CHECK: b.pl
87; CHECK: ret
88define void @test_add_tbz(i32 %a, i32 %b, i32* %ptr) {
89entry:
90  %add = add nsw i32 %a, %b
91  %cmp36 = icmp sge i32 %add, 0
92  br i1 %cmp36, label %L2, label %L1
93L1:
94  store i32 %add, i32* %ptr, align 8
95  br label %L2
96L2:
97  ret void
98}
99
100; CHECK-LABEL: test_subs_tbz:
101; CHECK: subs
102; CHECK: b.pl
103; CHECK: ret
104define void @test_subs_tbz(i32 %a, i32 %b, i32* %ptr) {
105entry:
106  %sub = sub nsw i32 %a, %b
107  %cmp36 = icmp sge i32 %sub, 0
108  br i1 %cmp36, label %L2, label %L1
109L1:
110  store i32 %sub, i32* %ptr, align 8
111  br label %L2
112L2:
113  ret void
114}
115
116; CHECK-LABEL: test_add_tbnz
117; CHECK: adds
118; CHECK: b.mi
119; CHECK: ret
120define void @test_add_tbnz(i32 %a, i32 %b, i32* %ptr) {
121entry:
122  %add = add nsw i32 %a, %b
123  %cmp36 = icmp slt i32 %add, 0
124  br i1 %cmp36, label %L2, label %L1
125L1:
126  store i32 %add, i32* %ptr, align 8
127  br label %L2
128L2:
129  ret void
130}
131
132; CHECK-LABEL: test_subs_tbnz
133; CHECK: subs
134; CHECK: b.mi
135; CHECK: ret
136define void @test_subs_tbnz(i32 %a, i32 %b, i32* %ptr) {
137entry:
138  %sub = sub nsw i32 %a, %b
139  %cmp36 = icmp slt i32 %sub, 0
140  br i1 %cmp36, label %L2, label %L1
141L1:
142  store i32 %sub, i32* %ptr, align 8
143  br label %L2
144L2:
145  ret void
146}
147
148declare void @foo()
149declare void @bar(i32)
150
151; Don't transform since the call will clobber the NZCV bits.
152; CHECK-LABEL: test_call_clobber:
153; CHECK: and w[[DST:[0-9]+]], w1, #0x6
154; CHECK: bl bar
155; CHECK: cbnz w[[DST]]
156define void @test_call_clobber(i32 %unused, i32 %a) {
157entry:
158  %c = and i32 %a, 6
159  call void @bar(i32 %c)
160  %tobool = icmp eq i32 %c, 0
161  br i1 %tobool, label %if.end, label %if.then
162
163if.then:
164  tail call void @foo()
165  unreachable
166
167if.end:
168  ret void
169}
170