1 ; RUN: llc < %s -O3 -mtriple=aarch64-eabi -verify-machineinstrs | FileCheck %s
3 target datalayout = "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128"
4 target triple = "aarch64-linaro-linux-gnueabi"
6 ; CMN is an alias of ADDS.
7 ; CHECK-LABEL: test_add_cbz:
11 define 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
16 store i32 0, i32* %ptr, align 4
19 store i32 1, i32* %ptr, align 4
23 ; CHECK-LABEL: test_add_cbz_multiple_use:
27 define 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
32 store i32 0, i32* %ptr, align 4
35 store i32 %c, i32* %ptr, align 4
39 ; CHECK-LABEL: test_add_cbz_64:
42 define 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
47 store i64 0, i64* %ptr, align 4
50 store i64 1, i64* %ptr, align 4
54 ; CHECK-LABEL: test_and_cbz:
57 define void @test_and_cbz(i32 %a, i32* %ptr) {
59 %d = icmp ne i32 %c, 0
60 br i1 %d, label %L1, label %L2
62 store i32 0, i32* %ptr, align 4
65 store i32 1, i32* %ptr, align 4
69 ; CHECK-LABEL: test_bic_cbnz:
70 ; CHECK: bics wzr, w1, w0
72 define void @test_bic_cbnz(i32 %a, i32 %b, i32* %ptr) {
74 %d = icmp eq i32 %c, %b
75 br i1 %d, label %L1, label %L2
77 store i32 0, i32* %ptr, align 4
80 store i32 1, i32* %ptr, align 4
84 ; CHECK-LABEL: test_add_tbz:
88 define void @test_add_tbz(i32 %a, i32 %b, i32* %ptr) {
90 %add = add nsw i32 %a, %b
91 %cmp36 = icmp sge i32 %add, 0
92 br i1 %cmp36, label %L2, label %L1
94 store i32 %add, i32* %ptr, align 8
100 ; CHECK-LABEL: test_subs_tbz:
104 define void @test_subs_tbz(i32 %a, i32 %b, i32* %ptr) {
106 %sub = sub nsw i32 %a, %b
107 %cmp36 = icmp sge i32 %sub, 0
108 br i1 %cmp36, label %L2, label %L1
110 store i32 %sub, i32* %ptr, align 8
116 ; CHECK-LABEL: test_add_tbnz
120 define void @test_add_tbnz(i32 %a, i32 %b, i32* %ptr) {
122 %add = add nsw i32 %a, %b
123 %cmp36 = icmp slt i32 %add, 0
124 br i1 %cmp36, label %L2, label %L1
126 store i32 %add, i32* %ptr, align 8
132 ; CHECK-LABEL: test_subs_tbnz
136 define void @test_subs_tbnz(i32 %a, i32 %b, i32* %ptr) {
138 %sub = sub nsw i32 %a, %b
139 %cmp36 = icmp slt i32 %sub, 0
140 br i1 %cmp36, label %L2, label %L1
142 store i32 %sub, i32* %ptr, align 8
149 declare void @bar(i32)
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
155 ; CHECK: cbnz w[[DST]]
156 define void @test_call_clobber(i32 %unused, i32 %a) {
159 call void @bar(i32 %c)
160 %tobool = icmp eq i32 %c, 0
161 br i1 %tobool, label %if.end, label %if.then
164 tail call void @foo()