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