1 ; RUN: llc -O3 < %s | FileCheck %s 2 target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-n32:64" 3 target triple = "arm64-unknown-unknown" 4 5 ; CHECK-LABEL: foo1 6 ; CHECK: cinc w{{[0-9]+}}, w{{[0-9]+}}, ne 7 define i32 @foo1(i32 %b, i32 %c) nounwind readnone ssp { 8 entry: 9 %not.tobool = icmp ne i32 %c, 0 10 %add = zext i1 %not.tobool to i32 11 %b.add = add i32 %c, %b 12 %add1 = add i32 %b.add, %add 13 ret i32 %add1 14 } 15 16 ; CHECK-LABEL: foo2 17 ; CHECK: cneg w{{[0-9]+}}, w{{[0-9]+}}, ne 18 define i32 @foo2(i32 %b, i32 %c) nounwind readnone ssp { 19 entry: 20 %mul = sub i32 0, %b 21 %tobool = icmp eq i32 %c, 0 22 %b.mul = select i1 %tobool, i32 %b, i32 %mul 23 %add = add nsw i32 %b.mul, %c 24 ret i32 %add 25 } 26 27 ; CHECK-LABEL: foo3 28 ; CHECK: cinv w{{[0-9]+}}, w{{[0-9]+}}, ne 29 define i32 @foo3(i32 %b, i32 %c) nounwind readnone ssp { 30 entry: 31 %not.tobool = icmp ne i32 %c, 0 32 %xor = sext i1 %not.tobool to i32 33 %b.xor = xor i32 %xor, %b 34 %add = add nsw i32 %b.xor, %c 35 ret i32 %add 36 } 37 38 ; rdar://11632325 39 define i32@foo4(i32 %a) nounwind ssp { 40 ; CHECK-LABEL: foo4 41 ; CHECK: cneg 42 ; CHECK-NEXT: ret 43 %cmp = icmp sgt i32 %a, -1 44 %neg = sub nsw i32 0, %a 45 %cond = select i1 %cmp, i32 %a, i32 %neg 46 ret i32 %cond 47 } 48 49 define i32@foo5(i32 %a, i32 %b) nounwind ssp { 50 entry: 51 ; CHECK-LABEL: foo5 52 ; CHECK: subs 53 ; CHECK-NEXT: cneg 54 ; CHECK-NEXT: ret 55 %sub = sub nsw i32 %a, %b 56 %cmp = icmp sgt i32 %sub, -1 57 %sub3 = sub nsw i32 0, %sub 58 %cond = select i1 %cmp, i32 %sub, i32 %sub3 59 ret i32 %cond 60 } 61 62 ; make sure we can handle branch instruction in optimizeCompare. 63 define i32@foo6(i32 %a, i32 %b) nounwind ssp { 64 ; CHECK-LABEL: foo6 65 ; CHECK: b 66 %sub = sub nsw i32 %a, %b 67 %cmp = icmp sgt i32 %sub, 0 68 br i1 %cmp, label %l.if, label %l.else 69 70 l.if: 71 ret i32 1 72 73 l.else: 74 ret i32 %sub 75 } 76 77 ; If CPSR is used multiple times and V flag is used, we don't remove cmp. 78 define i32 @foo7(i32 %a, i32 %b) nounwind { 79 entry: 80 ; CHECK-LABEL: foo7: 81 ; CHECK: sub 82 ; FIXME: Misspelled CHECK-NEXT 83 ; CHECK-next: adds 84 ; CHECK-next: csneg 85 ; CHECK-next: b 86 %sub = sub nsw i32 %a, %b 87 %cmp = icmp sgt i32 %sub, -1 88 %sub3 = sub nsw i32 0, %sub 89 %cond = select i1 %cmp, i32 %sub, i32 %sub3 90 br i1 %cmp, label %if.then, label %if.else 91 92 if.then: 93 %cmp2 = icmp slt i32 %sub, -1 94 %sel = select i1 %cmp2, i32 %cond, i32 %a 95 ret i32 %sel 96 97 if.else: 98 ret i32 %cond 99 } 100 101 define i32 @foo8(i32 %v, i32 %a, i32 %b) nounwind readnone ssp { 102 entry: 103 ; CHECK-LABEL: foo8: 104 ; CHECK: cmp w0, #0 105 ; CHECK: csinv w0, w1, w2, ne 106 %tobool = icmp eq i32 %v, 0 107 %neg = xor i32 -1, %b 108 %cond = select i1 %tobool, i32 %neg, i32 %a 109 ret i32 %cond 110 } 111 112 define i32 @foo9(i32 %v) nounwind readnone optsize ssp { 113 entry: 114 ; CHECK-LABEL: foo9: 115 ; CHECK: cmp w0, #0 116 ; CHECK: orr w[[REG:[0-9]+]], wzr, #0x4 117 ; CHECK: cinv w0, w[[REG]], eq 118 %tobool = icmp ne i32 %v, 0 119 %cond = select i1 %tobool, i32 4, i32 -5 120 ret i32 %cond 121 } 122 123 define i64 @foo10(i64 %v) nounwind readnone optsize ssp { 124 entry: 125 ; CHECK-LABEL: foo10: 126 ; CHECK: cmp x0, #0 127 ; CHECK: orr w[[REG:[0-9]+]], wzr, #0x4 128 ; CHECK: cinv x0, x[[REG]], eq 129 %tobool = icmp ne i64 %v, 0 130 %cond = select i1 %tobool, i64 4, i64 -5 131 ret i64 %cond 132 } 133 134 define i32 @foo11(i32 %v) nounwind readnone optsize ssp { 135 entry: 136 ; CHECK-LABEL: foo11: 137 ; CHECK: cmp w0, #0 138 ; CHECK: orr w[[REG:[0-9]+]], wzr, #0x4 139 ; CHECK: cneg w0, w[[REG]], eq 140 %tobool = icmp ne i32 %v, 0 141 %cond = select i1 %tobool, i32 4, i32 -4 142 ret i32 %cond 143 } 144 145 define i64 @foo12(i64 %v) nounwind readnone optsize ssp { 146 entry: 147 ; CHECK-LABEL: foo12: 148 ; CHECK: cmp x0, #0 149 ; CHECK: orr w[[REG:[0-9]+]], wzr, #0x4 150 ; CHECK: cneg x0, x[[REG]], eq 151 %tobool = icmp ne i64 %v, 0 152 %cond = select i1 %tobool, i64 4, i64 -4 153 ret i64 %cond 154 } 155 156 define i32 @foo13(i32 %v, i32 %a, i32 %b) nounwind readnone optsize ssp { 157 entry: 158 ; CHECK-LABEL: foo13: 159 ; CHECK: cmp w0, #0 160 ; CHECK: csneg w0, w1, w2, ne 161 %tobool = icmp eq i32 %v, 0 162 %sub = sub i32 0, %b 163 %cond = select i1 %tobool, i32 %sub, i32 %a 164 ret i32 %cond 165 } 166 167 define i64 @foo14(i64 %v, i64 %a, i64 %b) nounwind readnone optsize ssp { 168 entry: 169 ; CHECK-LABEL: foo14: 170 ; CHECK: cmp x0, #0 171 ; CHECK: csneg x0, x1, x2, ne 172 %tobool = icmp eq i64 %v, 0 173 %sub = sub i64 0, %b 174 %cond = select i1 %tobool, i64 %sub, i64 %a 175 ret i64 %cond 176 } 177 178 define i32 @foo15(i32 %a, i32 %b) nounwind readnone optsize ssp { 179 entry: 180 ; CHECK-LABEL: foo15: 181 ; CHECK: cmp w0, w1 182 ; CHECK: orr w[[REG:[0-9]+]], wzr, #0x1 183 ; CHECK: cinc w0, w[[REG]], gt 184 %cmp = icmp sgt i32 %a, %b 185 %. = select i1 %cmp, i32 2, i32 1 186 ret i32 %. 187 } 188 189 define i32 @foo16(i32 %a, i32 %b) nounwind readnone optsize ssp { 190 entry: 191 ; CHECK-LABEL: foo16: 192 ; CHECK: cmp w0, w1 193 ; CHECK: orr w[[REG:[0-9]+]], wzr, #0x1 194 ; CHECK: cinc w0, w[[REG]], le 195 %cmp = icmp sgt i32 %a, %b 196 %. = select i1 %cmp, i32 1, i32 2 197 ret i32 %. 198 } 199 200 define i64 @foo17(i64 %a, i64 %b) nounwind readnone optsize ssp { 201 entry: 202 ; CHECK-LABEL: foo17: 203 ; CHECK: cmp x0, x1 204 ; CHECK: orr w[[REG:[0-9]+]], wzr, #0x1 205 ; CHECK: cinc x0, x[[REG]], gt 206 %cmp = icmp sgt i64 %a, %b 207 %. = select i1 %cmp, i64 2, i64 1 208 ret i64 %. 209 } 210 211 define i64 @foo18(i64 %a, i64 %b) nounwind readnone optsize ssp { 212 entry: 213 ; CHECK-LABEL: foo18: 214 ; CHECK: cmp x0, x1 215 ; CHECK: orr w[[REG:[0-9]+]], wzr, #0x1 216 ; CHECK: cinc x0, x[[REG]], le 217 %cmp = icmp sgt i64 %a, %b 218 %. = select i1 %cmp, i64 1, i64 2 219 ret i64 %. 220 } 221 222 define i64 @foo19(i64 %a, i64 %b, i64 %c) { 223 entry: 224 ; CHECK-LABEL: foo19: 225 ; CHECK: cinc x0, x2 226 ; CHECK-NOT: add 227 %cmp = icmp ult i64 %a, %b 228 %inc = zext i1 %cmp to i64 229 %inc.c = add i64 %inc, %c 230 ret i64 %inc.c 231 } 232 233 define i32 @foo20(i32 %x) { 234 ; CHECK-LABEL: foo20: 235 ; CHECK: cmp w0, #5 236 ; CHECK: orr w[[REG:[0-9]+]], wzr, #0x6 237 ; CHECK: csinc w0, w[[REG]], wzr, eq 238 %cmp = icmp eq i32 %x, 5 239 %res = select i1 %cmp, i32 6, i32 1 240 ret i32 %res 241 } 242 243 define i64 @foo21(i64 %x) { 244 ; CHECK-LABEL: foo21: 245 ; CHECK: cmp x0, #5 246 ; CHECK: orr w[[REG:[0-9]+]], wzr, #0x6 247 ; CHECK: csinc x0, x[[REG]], xzr, eq 248 %cmp = icmp eq i64 %x, 5 249 %res = select i1 %cmp, i64 6, i64 1 250 ret i64 %res 251 } 252 253 define i32 @foo22(i32 %x) { 254 ; CHECK-LABEL: foo22: 255 ; CHECK: cmp w0, #5 256 ; CHECK: orr w[[REG:[0-9]+]], wzr, #0x6 257 ; CHECK: csinc w0, w[[REG]], wzr, ne 258 %cmp = icmp eq i32 %x, 5 259 %res = select i1 %cmp, i32 1, i32 6 260 ret i32 %res 261 } 262 263 define i64 @foo23(i64 %x) { 264 ; CHECK-LABEL: foo23: 265 ; CHECK: cmp x0, #5 266 ; CHECK: orr w[[REG:[0-9]+]], wzr, #0x6 267 ; CHECK: csinc x0, x[[REG]], xzr, ne 268 %cmp = icmp eq i64 %x, 5 269 %res = select i1 %cmp, i64 1, i64 6 270 ret i64 %res 271 } 272