1; RUN: llc -O3 < %s | FileCheck %s 2target 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" 3target triple = "arm64-unknown-unknown" 4 5; CHECK-LABEL: foo1 6; CHECK: cinc w{{[0-9]+}}, w{{[0-9]+}}, ne 7define i32 @foo1(i32 %b, i32 %c) nounwind readnone ssp { 8entry: 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 18define i32 @foo2(i32 %b, i32 %c) nounwind readnone ssp { 19entry: 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 29define i32 @foo3(i32 %b, i32 %c) nounwind readnone ssp { 30entry: 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 39define 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 49define i32@foo5(i32 %a, i32 %b) nounwind ssp { 50entry: 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. 63define 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 70l.if: 71 ret i32 1 72 73l.else: 74 ret i32 %sub 75} 76 77; If CPSR is used multiple times and V flag is used, we don't remove cmp. 78define i32 @foo7(i32 %a, i32 %b) nounwind { 79entry: 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 92if.then: 93 %cmp2 = icmp slt i32 %sub, -1 94 %sel = select i1 %cmp2, i32 %cond, i32 %a 95 ret i32 %sel 96 97if.else: 98 ret i32 %cond 99} 100 101define i32 @foo8(i32 %v, i32 %a, i32 %b) nounwind readnone ssp { 102entry: 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 112define i32 @foo9(i32 %v) nounwind readnone optsize ssp { 113entry: 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 123define i64 @foo10(i64 %v) nounwind readnone optsize ssp { 124entry: 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 134define i32 @foo11(i32 %v) nounwind readnone optsize ssp { 135entry: 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 145define i64 @foo12(i64 %v) nounwind readnone optsize ssp { 146entry: 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 156define i32 @foo13(i32 %v, i32 %a, i32 %b) nounwind readnone optsize ssp { 157entry: 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 167define i64 @foo14(i64 %v, i64 %a, i64 %b) nounwind readnone optsize ssp { 168entry: 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 178define i32 @foo15(i32 %a, i32 %b) nounwind readnone optsize ssp { 179entry: 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 189define i32 @foo16(i32 %a, i32 %b) nounwind readnone optsize ssp { 190entry: 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 200define i64 @foo17(i64 %a, i64 %b) nounwind readnone optsize ssp { 201entry: 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 211define i64 @foo18(i64 %a, i64 %b) nounwind readnone optsize ssp { 212entry: 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 222define i64 @foo19(i64 %a, i64 %b, i64 %c) { 223entry: 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 233define 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 243define 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 253define 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 263define 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