1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2 ; RUN: llc -mtriple=aarch64-- -o - < %s | FileCheck %s
4 ; Verify that we can fold csneg/csel into csinc instruction.
6 target datalayout = "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128"
7 target triple = "aarch64-unknown-linux-gnu"
9 ; int csinc1 (int a, int b) { return !a ? b+3 : b+1; }
10 define i32 @csinc1(i32 %a, i32 %b) {
11 ; CHECK-LABEL: csinc1:
12 ; CHECK: // %bb.0: // %entry
13 ; CHECK-NEXT: cmp w0, #0
14 ; CHECK-NEXT: add w8, w1, #3
15 ; CHECK-NEXT: csinc w0, w8, w1, eq
18 %tobool.not = icmp eq i32 %a, 0
19 %cond.v = select i1 %tobool.not, i32 3, i32 1
20 %cond = add nsw i32 %cond.v, %b
24 ; int csinc2 (int a, int b) { return a ? b+3 : b+1; }
25 define i32 @csinc2(i32 %a, i32 %b) {
26 ; CHECK-LABEL: csinc2:
27 ; CHECK: // %bb.0: // %entry
28 ; CHECK-NEXT: cmp w0, #0
29 ; CHECK-NEXT: add w8, w1, #3
30 ; CHECK-NEXT: csinc w0, w8, w1, ne
33 %tobool.not = icmp eq i32 %a, 0
34 %cond.v = select i1 %tobool.not, i32 1, i32 3
35 %cond = add nsw i32 %cond.v, %b
39 ; int csinc3 (int a, int b) { return !a ? b+1 : b-3; }
40 define i32 @csinc3(i32 %a, i32 %b) {
41 ; CHECK-LABEL: csinc3:
42 ; CHECK: // %bb.0: // %entry
43 ; CHECK-NEXT: sub w8, w1, #3
44 ; CHECK-NEXT: cmp w0, #0
45 ; CHECK-NEXT: csinc w0, w8, w1, ne
48 %tobool.not = icmp eq i32 %a, 0
49 %cond.v = select i1 %tobool.not, i32 1, i32 -3
50 %cond = add nsw i32 %cond.v, %b
54 ; int csinc4 (int a, int b) { return a ? b+1 : b-3; }
55 define i32 @csinc4(i32 %a, i32 %b) {
56 ; CHECK-LABEL: csinc4:
57 ; CHECK: // %bb.0: // %entry
58 ; CHECK-NEXT: sub w8, w1, #3
59 ; CHECK-NEXT: cmp w0, #0
60 ; CHECK-NEXT: csinc w0, w8, w1, eq
63 %tobool.not = icmp eq i32 %a, 0
64 %cond.v = select i1 %tobool.not, i32 -3, i32 1
65 %cond = add nsw i32 %cond.v, %b
69 ; int csinc5 (int a, int b) { return a ? b+1 : b-4095; }
70 define i32 @csinc5(i32 %a, i32 %b) {
71 ; CHECK-LABEL: csinc5:
72 ; CHECK: // %bb.0: // %entry
73 ; CHECK-NEXT: sub w8, w1, #4095
74 ; CHECK-NEXT: cmp w0, #0
75 ; CHECK-NEXT: csinc w0, w8, w1, eq
78 %tobool.not = icmp eq i32 %a, 0
79 %cond.v = select i1 %tobool.not, i32 -4095, i32 1
80 %cond = add nsw i32 %cond.v, %b
84 ; int csinc6 (int a, int b) { return a ? b+1 : b-4096; }
85 define i32 @csinc6(i32 %a, i32 %b) {
86 ; CHECK-LABEL: csinc6:
87 ; CHECK: // %bb.0: // %entry
88 ; CHECK-NEXT: sub w8, w1, #1, lsl #12 // =4096
89 ; CHECK-NEXT: cmp w0, #0
90 ; CHECK-NEXT: csinc w0, w8, w1, eq
93 %tobool.not = icmp eq i32 %a, 0
94 %cond.v = select i1 %tobool.not, i32 -4096, i32 1
95 %cond = add nsw i32 %cond.v, %b
99 ; prevent larger constants (the add laid after csinc)
100 ; int csinc7 (int a, int b) { return a ? b+1 : b-4097; }
101 define i32 @csinc7(i32 %a, i32 %b) {
102 ; CHECK-LABEL: csinc7:
103 ; CHECK: // %bb.0: // %entry
104 ; CHECK-NEXT: mov w8, #-4097 // =0xffffefff
105 ; CHECK-NEXT: cmp w0, #0
106 ; CHECK-NEXT: csinc w8, w8, wzr, eq
107 ; CHECK-NEXT: add w0, w8, w1
110 %tobool.not = icmp eq i32 %a, 0
111 %cond.v = select i1 %tobool.not, i32 -4097, i32 1
112 %cond = add nsw i32 %cond.v, %b
116 ; int csinc8 (int a, int b) { return a ? b-1 : b+1; }
117 define i32 @csinc8(i32 %a, i32 %b) {
118 ; CHECK-LABEL: csinc8:
119 ; CHECK: // %bb.0: // %entry
120 ; CHECK-NEXT: sub w8, w1, #1
121 ; CHECK-NEXT: cmp w0, #0
122 ; CHECK-NEXT: csinc w0, w8, w1, ne
125 %tobool.not = icmp eq i32 %a, 0
126 %cond.v = select i1 %tobool.not, i32 1, i32 -1
127 %cond = add nsw i32 %cond.v, %b
131 ; int csinc9 (int a, int b) { return a ? b+1 : b-1; }
132 define i32 @csinc9(i32 %a, i32 %b) {
133 ; CHECK-LABEL: csinc9:
134 ; CHECK: // %bb.0: // %entry
135 ; CHECK-NEXT: sub w8, w1, #1
136 ; CHECK-NEXT: cmp w0, #0
137 ; CHECK-NEXT: csinc w0, w8, w1, eq
140 %tobool.not = icmp eq i32 %a, 0
141 %cond.v = select i1 %tobool.not, i32 -1, i32 1
142 %cond = add nsw i32 %cond.v, %b