1*9880d681SAndroid Build Coastguard Worker; RUN: llc < %s -mcpu=cyclone -verify-machineinstrs -aarch64-ccmp -aarch64-stress-ccmp | FileCheck %s 2*9880d681SAndroid Build Coastguard Workertarget triple = "arm64-apple-ios" 3*9880d681SAndroid Build Coastguard Worker 4*9880d681SAndroid Build Coastguard Worker; CHECK: single_same 5*9880d681SAndroid Build Coastguard Worker; CHECK: cmp w0, #5 6*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ccmp w1, #17, #4, ne 7*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: b.ne 8*9880d681SAndroid Build Coastguard Worker; CHECK: %if.then 9*9880d681SAndroid Build Coastguard Worker; CHECK: bl _foo 10*9880d681SAndroid Build Coastguard Worker; CHECK: %if.end 11*9880d681SAndroid Build Coastguard Workerdefine i32 @single_same(i32 %a, i32 %b) nounwind ssp { 12*9880d681SAndroid Build Coastguard Workerentry: 13*9880d681SAndroid Build Coastguard Worker %cmp = icmp eq i32 %a, 5 14*9880d681SAndroid Build Coastguard Worker %cmp1 = icmp eq i32 %b, 17 15*9880d681SAndroid Build Coastguard Worker %or.cond = or i1 %cmp, %cmp1 16*9880d681SAndroid Build Coastguard Worker br i1 %or.cond, label %if.then, label %if.end 17*9880d681SAndroid Build Coastguard Worker 18*9880d681SAndroid Build Coastguard Workerif.then: 19*9880d681SAndroid Build Coastguard Worker %call = tail call i32 @foo() nounwind 20*9880d681SAndroid Build Coastguard Worker br label %if.end 21*9880d681SAndroid Build Coastguard Worker 22*9880d681SAndroid Build Coastguard Workerif.end: 23*9880d681SAndroid Build Coastguard Worker ret i32 7 24*9880d681SAndroid Build Coastguard Worker} 25*9880d681SAndroid Build Coastguard Worker 26*9880d681SAndroid Build Coastguard Worker; Different condition codes for the two compares. 27*9880d681SAndroid Build Coastguard Worker; CHECK: single_different 28*9880d681SAndroid Build Coastguard Worker; CHECK: cmp w0, #6 29*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ccmp w1, #17, #0, ge 30*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: b.eq 31*9880d681SAndroid Build Coastguard Worker; CHECK: %if.then 32*9880d681SAndroid Build Coastguard Worker; CHECK: bl _foo 33*9880d681SAndroid Build Coastguard Worker; CHECK: %if.end 34*9880d681SAndroid Build Coastguard Workerdefine i32 @single_different(i32 %a, i32 %b) nounwind ssp { 35*9880d681SAndroid Build Coastguard Workerentry: 36*9880d681SAndroid Build Coastguard Worker %cmp = icmp sle i32 %a, 5 37*9880d681SAndroid Build Coastguard Worker %cmp1 = icmp ne i32 %b, 17 38*9880d681SAndroid Build Coastguard Worker %or.cond = or i1 %cmp, %cmp1 39*9880d681SAndroid Build Coastguard Worker br i1 %or.cond, label %if.then, label %if.end 40*9880d681SAndroid Build Coastguard Worker 41*9880d681SAndroid Build Coastguard Workerif.then: 42*9880d681SAndroid Build Coastguard Worker %call = tail call i32 @foo() nounwind 43*9880d681SAndroid Build Coastguard Worker br label %if.end 44*9880d681SAndroid Build Coastguard Worker 45*9880d681SAndroid Build Coastguard Workerif.end: 46*9880d681SAndroid Build Coastguard Worker ret i32 7 47*9880d681SAndroid Build Coastguard Worker} 48*9880d681SAndroid Build Coastguard Worker 49*9880d681SAndroid Build Coastguard Worker; Second block clobbers the flags, can't convert (easily). 50*9880d681SAndroid Build Coastguard Worker; CHECK: single_flagclobber 51*9880d681SAndroid Build Coastguard Worker; CHECK: cmp 52*9880d681SAndroid Build Coastguard Worker; CHECK: b.eq 53*9880d681SAndroid Build Coastguard Worker; CHECK: cmp 54*9880d681SAndroid Build Coastguard Worker; CHECK: b.gt 55*9880d681SAndroid Build Coastguard Workerdefine i32 @single_flagclobber(i32 %a, i32 %b) nounwind ssp { 56*9880d681SAndroid Build Coastguard Workerentry: 57*9880d681SAndroid Build Coastguard Worker %cmp = icmp eq i32 %a, 5 58*9880d681SAndroid Build Coastguard Worker br i1 %cmp, label %if.then, label %lor.lhs.false 59*9880d681SAndroid Build Coastguard Worker 60*9880d681SAndroid Build Coastguard Workerlor.lhs.false: ; preds = %entry 61*9880d681SAndroid Build Coastguard Worker %cmp1 = icmp slt i32 %b, 7 62*9880d681SAndroid Build Coastguard Worker %mul = shl nsw i32 %b, 1 63*9880d681SAndroid Build Coastguard Worker %add = add nsw i32 %b, 1 64*9880d681SAndroid Build Coastguard Worker %cond = select i1 %cmp1, i32 %mul, i32 %add 65*9880d681SAndroid Build Coastguard Worker %cmp2 = icmp slt i32 %cond, 17 66*9880d681SAndroid Build Coastguard Worker br i1 %cmp2, label %if.then, label %if.end 67*9880d681SAndroid Build Coastguard Worker 68*9880d681SAndroid Build Coastguard Workerif.then: ; preds = %lor.lhs.false, %entry 69*9880d681SAndroid Build Coastguard Worker %call = tail call i32 @foo() nounwind 70*9880d681SAndroid Build Coastguard Worker br label %if.end 71*9880d681SAndroid Build Coastguard Worker 72*9880d681SAndroid Build Coastguard Workerif.end: ; preds = %if.then, %lor.lhs.false 73*9880d681SAndroid Build Coastguard Worker ret i32 7 74*9880d681SAndroid Build Coastguard Worker} 75*9880d681SAndroid Build Coastguard Worker 76*9880d681SAndroid Build Coastguard Worker; Second block clobbers the flags and ends with a tbz terminator. 77*9880d681SAndroid Build Coastguard Worker; CHECK: single_flagclobber_tbz 78*9880d681SAndroid Build Coastguard Worker; CHECK: cmp 79*9880d681SAndroid Build Coastguard Worker; CHECK: b.eq 80*9880d681SAndroid Build Coastguard Worker; CHECK: cmp 81*9880d681SAndroid Build Coastguard Worker; CHECK: tbz 82*9880d681SAndroid Build Coastguard Workerdefine i32 @single_flagclobber_tbz(i32 %a, i32 %b) nounwind ssp { 83*9880d681SAndroid Build Coastguard Workerentry: 84*9880d681SAndroid Build Coastguard Worker %cmp = icmp eq i32 %a, 5 85*9880d681SAndroid Build Coastguard Worker br i1 %cmp, label %if.then, label %lor.lhs.false 86*9880d681SAndroid Build Coastguard Worker 87*9880d681SAndroid Build Coastguard Workerlor.lhs.false: ; preds = %entry 88*9880d681SAndroid Build Coastguard Worker %cmp1 = icmp slt i32 %b, 7 89*9880d681SAndroid Build Coastguard Worker %mul = shl nsw i32 %b, 1 90*9880d681SAndroid Build Coastguard Worker %add = add nsw i32 %b, 1 91*9880d681SAndroid Build Coastguard Worker %cond = select i1 %cmp1, i32 %mul, i32 %add 92*9880d681SAndroid Build Coastguard Worker %and = and i32 %cond, 8 93*9880d681SAndroid Build Coastguard Worker %cmp2 = icmp ne i32 %and, 0 94*9880d681SAndroid Build Coastguard Worker br i1 %cmp2, label %if.then, label %if.end 95*9880d681SAndroid Build Coastguard Worker 96*9880d681SAndroid Build Coastguard Workerif.then: ; preds = %lor.lhs.false, %entry 97*9880d681SAndroid Build Coastguard Worker %call = tail call i32 @foo() nounwind 98*9880d681SAndroid Build Coastguard Worker br label %if.end 99*9880d681SAndroid Build Coastguard Worker 100*9880d681SAndroid Build Coastguard Workerif.end: ; preds = %if.then, %lor.lhs.false 101*9880d681SAndroid Build Coastguard Worker ret i32 7 102*9880d681SAndroid Build Coastguard Worker} 103*9880d681SAndroid Build Coastguard Worker 104*9880d681SAndroid Build Coastguard Worker; Speculatively execute division by zero. 105*9880d681SAndroid Build Coastguard Worker; The sdiv/udiv instructions do not trap when the divisor is zero, so they are 106*9880d681SAndroid Build Coastguard Worker; safe to speculate. 107*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: speculate_division: 108*9880d681SAndroid Build Coastguard Worker; CHECK: cmp w0, #1 109*9880d681SAndroid Build Coastguard Worker; CHECK: sdiv [[DIVRES:w[0-9]+]], w1, w0 110*9880d681SAndroid Build Coastguard Worker; CHECK: ccmp [[DIVRES]], #16, #0, ge 111*9880d681SAndroid Build Coastguard Worker; CHECK: b.gt [[BLOCK:LBB[0-9_]+]] 112*9880d681SAndroid Build Coastguard Worker; CHECK: bl _foo 113*9880d681SAndroid Build Coastguard Worker; CHECK: [[BLOCK]]: 114*9880d681SAndroid Build Coastguard Worker; CHECK: orr w0, wzr, #0x7 115*9880d681SAndroid Build Coastguard Workerdefine i32 @speculate_division(i32 %a, i32 %b) nounwind ssp { 116*9880d681SAndroid Build Coastguard Workerentry: 117*9880d681SAndroid Build Coastguard Worker %cmp = icmp sgt i32 %a, 0 118*9880d681SAndroid Build Coastguard Worker br i1 %cmp, label %land.lhs.true, label %if.end 119*9880d681SAndroid Build Coastguard Worker 120*9880d681SAndroid Build Coastguard Workerland.lhs.true: 121*9880d681SAndroid Build Coastguard Worker %div = sdiv i32 %b, %a 122*9880d681SAndroid Build Coastguard Worker %cmp1 = icmp slt i32 %div, 17 123*9880d681SAndroid Build Coastguard Worker br i1 %cmp1, label %if.then, label %if.end 124*9880d681SAndroid Build Coastguard Worker 125*9880d681SAndroid Build Coastguard Workerif.then: 126*9880d681SAndroid Build Coastguard Worker %call = tail call i32 @foo() nounwind 127*9880d681SAndroid Build Coastguard Worker br label %if.end 128*9880d681SAndroid Build Coastguard Worker 129*9880d681SAndroid Build Coastguard Workerif.end: 130*9880d681SAndroid Build Coastguard Worker ret i32 7 131*9880d681SAndroid Build Coastguard Worker} 132*9880d681SAndroid Build Coastguard Worker 133*9880d681SAndroid Build Coastguard Worker; Floating point compare. 134*9880d681SAndroid Build Coastguard Worker; CHECK: single_fcmp 135*9880d681SAndroid Build Coastguard Worker; CHECK: cmp 136*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: b. 137*9880d681SAndroid Build Coastguard Worker; CHECK: fccmp {{.*}}, #8, ge 138*9880d681SAndroid Build Coastguard Worker; CHECK: b.lt 139*9880d681SAndroid Build Coastguard Workerdefine i32 @single_fcmp(i32 %a, float %b) nounwind ssp { 140*9880d681SAndroid Build Coastguard Workerentry: 141*9880d681SAndroid Build Coastguard Worker %cmp = icmp sgt i32 %a, 0 142*9880d681SAndroid Build Coastguard Worker br i1 %cmp, label %land.lhs.true, label %if.end 143*9880d681SAndroid Build Coastguard Worker 144*9880d681SAndroid Build Coastguard Workerland.lhs.true: 145*9880d681SAndroid Build Coastguard Worker %conv = sitofp i32 %a to float 146*9880d681SAndroid Build Coastguard Worker %div = fdiv float %b, %conv 147*9880d681SAndroid Build Coastguard Worker %cmp1 = fcmp oge float %div, 1.700000e+01 148*9880d681SAndroid Build Coastguard Worker br i1 %cmp1, label %if.then, label %if.end 149*9880d681SAndroid Build Coastguard Worker 150*9880d681SAndroid Build Coastguard Workerif.then: 151*9880d681SAndroid Build Coastguard Worker %call = tail call i32 @foo() nounwind 152*9880d681SAndroid Build Coastguard Worker br label %if.end 153*9880d681SAndroid Build Coastguard Worker 154*9880d681SAndroid Build Coastguard Workerif.end: 155*9880d681SAndroid Build Coastguard Worker ret i32 7 156*9880d681SAndroid Build Coastguard Worker} 157*9880d681SAndroid Build Coastguard Worker 158*9880d681SAndroid Build Coastguard Worker; Chain multiple compares. 159*9880d681SAndroid Build Coastguard Worker; CHECK: multi_different 160*9880d681SAndroid Build Coastguard Worker; CHECK: cmp 161*9880d681SAndroid Build Coastguard Worker; CHECK: ccmp 162*9880d681SAndroid Build Coastguard Worker; CHECK: ccmp 163*9880d681SAndroid Build Coastguard Worker; CHECK: b. 164*9880d681SAndroid Build Coastguard Workerdefine void @multi_different(i32 %a, i32 %b, i32 %c) nounwind ssp { 165*9880d681SAndroid Build Coastguard Workerentry: 166*9880d681SAndroid Build Coastguard Worker %cmp = icmp sgt i32 %a, %b 167*9880d681SAndroid Build Coastguard Worker br i1 %cmp, label %land.lhs.true, label %if.end 168*9880d681SAndroid Build Coastguard Worker 169*9880d681SAndroid Build Coastguard Workerland.lhs.true: 170*9880d681SAndroid Build Coastguard Worker %div = sdiv i32 %b, %a 171*9880d681SAndroid Build Coastguard Worker %cmp1 = icmp eq i32 %div, 5 172*9880d681SAndroid Build Coastguard Worker %cmp4 = icmp sgt i32 %div, %c 173*9880d681SAndroid Build Coastguard Worker %or.cond = and i1 %cmp1, %cmp4 174*9880d681SAndroid Build Coastguard Worker br i1 %or.cond, label %if.then, label %if.end 175*9880d681SAndroid Build Coastguard Worker 176*9880d681SAndroid Build Coastguard Workerif.then: 177*9880d681SAndroid Build Coastguard Worker %call = tail call i32 @foo() nounwind 178*9880d681SAndroid Build Coastguard Worker br label %if.end 179*9880d681SAndroid Build Coastguard Worker 180*9880d681SAndroid Build Coastguard Workerif.end: 181*9880d681SAndroid Build Coastguard Worker ret void 182*9880d681SAndroid Build Coastguard Worker} 183*9880d681SAndroid Build Coastguard Worker 184*9880d681SAndroid Build Coastguard Worker; Convert a cbz in the head block. 185*9880d681SAndroid Build Coastguard Worker; CHECK: cbz_head 186*9880d681SAndroid Build Coastguard Worker; CHECK: cmp w0, #0 187*9880d681SAndroid Build Coastguard Worker; CHECK: ccmp 188*9880d681SAndroid Build Coastguard Workerdefine i32 @cbz_head(i32 %a, i32 %b) nounwind ssp { 189*9880d681SAndroid Build Coastguard Workerentry: 190*9880d681SAndroid Build Coastguard Worker %cmp = icmp eq i32 %a, 0 191*9880d681SAndroid Build Coastguard Worker %cmp1 = icmp ne i32 %b, 17 192*9880d681SAndroid Build Coastguard Worker %or.cond = or i1 %cmp, %cmp1 193*9880d681SAndroid Build Coastguard Worker br i1 %or.cond, label %if.then, label %if.end 194*9880d681SAndroid Build Coastguard Worker 195*9880d681SAndroid Build Coastguard Workerif.then: 196*9880d681SAndroid Build Coastguard Worker %call = tail call i32 @foo() nounwind 197*9880d681SAndroid Build Coastguard Worker br label %if.end 198*9880d681SAndroid Build Coastguard Worker 199*9880d681SAndroid Build Coastguard Workerif.end: 200*9880d681SAndroid Build Coastguard Worker ret i32 7 201*9880d681SAndroid Build Coastguard Worker} 202*9880d681SAndroid Build Coastguard Worker 203*9880d681SAndroid Build Coastguard Worker; Check that the immediate operand is in range. The ccmp instruction encodes a 204*9880d681SAndroid Build Coastguard Worker; smaller range of immediates than subs/adds. 205*9880d681SAndroid Build Coastguard Worker; The ccmp immediates must be in the range 0-31. 206*9880d681SAndroid Build Coastguard Worker; CHECK: immediate_range 207*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: ccmp 208*9880d681SAndroid Build Coastguard Workerdefine i32 @immediate_range(i32 %a, i32 %b) nounwind ssp { 209*9880d681SAndroid Build Coastguard Workerentry: 210*9880d681SAndroid Build Coastguard Worker %cmp = icmp eq i32 %a, 5 211*9880d681SAndroid Build Coastguard Worker %cmp1 = icmp eq i32 %b, 32 212*9880d681SAndroid Build Coastguard Worker %or.cond = or i1 %cmp, %cmp1 213*9880d681SAndroid Build Coastguard Worker br i1 %or.cond, label %if.then, label %if.end 214*9880d681SAndroid Build Coastguard Worker 215*9880d681SAndroid Build Coastguard Workerif.then: 216*9880d681SAndroid Build Coastguard Worker %call = tail call i32 @foo() nounwind 217*9880d681SAndroid Build Coastguard Worker br label %if.end 218*9880d681SAndroid Build Coastguard Worker 219*9880d681SAndroid Build Coastguard Workerif.end: 220*9880d681SAndroid Build Coastguard Worker ret i32 7 221*9880d681SAndroid Build Coastguard Worker} 222*9880d681SAndroid Build Coastguard Worker 223*9880d681SAndroid Build Coastguard Worker; Convert a cbz in the second block. 224*9880d681SAndroid Build Coastguard Worker; CHECK: cbz_second 225*9880d681SAndroid Build Coastguard Worker; CHECK: cmp w0, #0 226*9880d681SAndroid Build Coastguard Worker; CHECK: ccmp w1, #0, #0, ne 227*9880d681SAndroid Build Coastguard Worker; CHECK: b.eq 228*9880d681SAndroid Build Coastguard Workerdefine i32 @cbz_second(i32 %a, i32 %b) nounwind ssp { 229*9880d681SAndroid Build Coastguard Workerentry: 230*9880d681SAndroid Build Coastguard Worker %cmp = icmp eq i32 %a, 0 231*9880d681SAndroid Build Coastguard Worker %cmp1 = icmp ne i32 %b, 0 232*9880d681SAndroid Build Coastguard Worker %or.cond = or i1 %cmp, %cmp1 233*9880d681SAndroid Build Coastguard Worker br i1 %or.cond, label %if.then, label %if.end 234*9880d681SAndroid Build Coastguard Worker 235*9880d681SAndroid Build Coastguard Workerif.then: 236*9880d681SAndroid Build Coastguard Worker %call = tail call i32 @foo() nounwind 237*9880d681SAndroid Build Coastguard Worker br label %if.end 238*9880d681SAndroid Build Coastguard Worker 239*9880d681SAndroid Build Coastguard Workerif.end: 240*9880d681SAndroid Build Coastguard Worker ret i32 7 241*9880d681SAndroid Build Coastguard Worker} 242*9880d681SAndroid Build Coastguard Worker 243*9880d681SAndroid Build Coastguard Worker; Convert a cbnz in the second block. 244*9880d681SAndroid Build Coastguard Worker; CHECK: cbnz_second 245*9880d681SAndroid Build Coastguard Worker; CHECK: cmp w0, #0 246*9880d681SAndroid Build Coastguard Worker; CHECK: ccmp w1, #0, #4, ne 247*9880d681SAndroid Build Coastguard Worker; CHECK: b.ne 248*9880d681SAndroid Build Coastguard Workerdefine i32 @cbnz_second(i32 %a, i32 %b) nounwind ssp { 249*9880d681SAndroid Build Coastguard Workerentry: 250*9880d681SAndroid Build Coastguard Worker %cmp = icmp eq i32 %a, 0 251*9880d681SAndroid Build Coastguard Worker %cmp1 = icmp eq i32 %b, 0 252*9880d681SAndroid Build Coastguard Worker %or.cond = or i1 %cmp, %cmp1 253*9880d681SAndroid Build Coastguard Worker br i1 %or.cond, label %if.then, label %if.end 254*9880d681SAndroid Build Coastguard Worker 255*9880d681SAndroid Build Coastguard Workerif.then: 256*9880d681SAndroid Build Coastguard Worker %call = tail call i32 @foo() nounwind 257*9880d681SAndroid Build Coastguard Worker br label %if.end 258*9880d681SAndroid Build Coastguard Worker 259*9880d681SAndroid Build Coastguard Workerif.end: 260*9880d681SAndroid Build Coastguard Worker ret i32 7 261*9880d681SAndroid Build Coastguard Worker} 262*9880d681SAndroid Build Coastguard Workerdeclare i32 @foo() 263*9880d681SAndroid Build Coastguard Worker 264*9880d681SAndroid Build Coastguard Worker%str1 = type { %str2 } 265*9880d681SAndroid Build Coastguard Worker%str2 = type { [24 x i8], i8*, i32, %str1*, i32, [4 x i8], %str1*, %str1*, %str1*, %str1*, %str1*, %str1*, %str1*, %str1*, %str1*, i8*, i8, i8*, %str1*, i8* } 266*9880d681SAndroid Build Coastguard Worker 267*9880d681SAndroid Build Coastguard Worker; Test case distilled from 126.gcc. 268*9880d681SAndroid Build Coastguard Worker; The phi in sw.bb.i.i gets multiple operands for the %entry predecessor. 269*9880d681SAndroid Build Coastguard Worker; CHECK: build_modify_expr 270*9880d681SAndroid Build Coastguard Workerdefine void @build_modify_expr() nounwind ssp { 271*9880d681SAndroid Build Coastguard Workerentry: 272*9880d681SAndroid Build Coastguard Worker switch i32 undef, label %sw.bb.i.i [ 273*9880d681SAndroid Build Coastguard Worker i32 69, label %if.end85 274*9880d681SAndroid Build Coastguard Worker i32 70, label %if.end85 275*9880d681SAndroid Build Coastguard Worker i32 71, label %if.end85 276*9880d681SAndroid Build Coastguard Worker i32 72, label %if.end85 277*9880d681SAndroid Build Coastguard Worker i32 73, label %if.end85 278*9880d681SAndroid Build Coastguard Worker i32 105, label %if.end85 279*9880d681SAndroid Build Coastguard Worker i32 106, label %if.end85 280*9880d681SAndroid Build Coastguard Worker ] 281*9880d681SAndroid Build Coastguard Worker 282*9880d681SAndroid Build Coastguard Workerif.end85: 283*9880d681SAndroid Build Coastguard Worker ret void 284*9880d681SAndroid Build Coastguard Worker 285*9880d681SAndroid Build Coastguard Workersw.bb.i.i: 286*9880d681SAndroid Build Coastguard Worker %ref.tr.i.i = phi %str1* [ %0, %sw.bb.i.i ], [ undef, %entry ] 287*9880d681SAndroid Build Coastguard Worker %operands.i.i = getelementptr inbounds %str1, %str1* %ref.tr.i.i, i64 0, i32 0, i32 2 288*9880d681SAndroid Build Coastguard Worker %arrayidx.i.i = bitcast i32* %operands.i.i to %str1** 289*9880d681SAndroid Build Coastguard Worker %0 = load %str1*, %str1** %arrayidx.i.i, align 8 290*9880d681SAndroid Build Coastguard Worker %code1.i.i.phi.trans.insert = getelementptr inbounds %str1, %str1* %0, i64 0, i32 0, i32 0, i64 16 291*9880d681SAndroid Build Coastguard Worker br label %sw.bb.i.i 292*9880d681SAndroid Build Coastguard Worker} 293*9880d681SAndroid Build Coastguard Worker 294*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: select_and 295*9880d681SAndroid Build Coastguard Workerdefine i64 @select_and(i32 %w0, i32 %w1, i64 %x2, i64 %x3) { 296*9880d681SAndroid Build Coastguard Worker; CHECK: cmp w1, #5 297*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ccmp w0, w1, #0, ne 298*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: csel x0, x2, x3, lt 299*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret 300*9880d681SAndroid Build Coastguard Worker %1 = icmp slt i32 %w0, %w1 301*9880d681SAndroid Build Coastguard Worker %2 = icmp ne i32 5, %w1 302*9880d681SAndroid Build Coastguard Worker %3 = and i1 %1, %2 303*9880d681SAndroid Build Coastguard Worker %sel = select i1 %3, i64 %x2, i64 %x3 304*9880d681SAndroid Build Coastguard Worker ret i64 %sel 305*9880d681SAndroid Build Coastguard Worker} 306*9880d681SAndroid Build Coastguard Worker 307*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: select_or 308*9880d681SAndroid Build Coastguard Workerdefine i64 @select_or(i32 %w0, i32 %w1, i64 %x2, i64 %x3) { 309*9880d681SAndroid Build Coastguard Worker; CHECK: cmp w1, #5 310*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ccmp w0, w1, #8, eq 311*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: csel x0, x2, x3, lt 312*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret 313*9880d681SAndroid Build Coastguard Worker %1 = icmp slt i32 %w0, %w1 314*9880d681SAndroid Build Coastguard Worker %2 = icmp ne i32 5, %w1 315*9880d681SAndroid Build Coastguard Worker %3 = or i1 %1, %2 316*9880d681SAndroid Build Coastguard Worker %sel = select i1 %3, i64 %x2, i64 %x3 317*9880d681SAndroid Build Coastguard Worker ret i64 %sel 318*9880d681SAndroid Build Coastguard Worker} 319*9880d681SAndroid Build Coastguard Worker 320*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: gccbug 321*9880d681SAndroid Build Coastguard Workerdefine i64 @gccbug(i64 %x0, i64 %x1) { 322*9880d681SAndroid Build Coastguard Worker; CHECK: cmp x0, #2 323*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ccmp x0, #4, #4, ne 324*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ccmp x1, #0, #0, eq 325*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: orr w[[REGNUM:[0-9]+]], wzr, #0x1 326*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: cinc x0, x[[REGNUM]], eq 327*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret 328*9880d681SAndroid Build Coastguard Worker %cmp0 = icmp eq i64 %x1, 0 329*9880d681SAndroid Build Coastguard Worker %cmp1 = icmp eq i64 %x0, 2 330*9880d681SAndroid Build Coastguard Worker %cmp2 = icmp eq i64 %x0, 4 331*9880d681SAndroid Build Coastguard Worker 332*9880d681SAndroid Build Coastguard Worker %or = or i1 %cmp2, %cmp1 333*9880d681SAndroid Build Coastguard Worker %and = and i1 %or, %cmp0 334*9880d681SAndroid Build Coastguard Worker 335*9880d681SAndroid Build Coastguard Worker %sel = select i1 %and, i64 2, i64 1 336*9880d681SAndroid Build Coastguard Worker ret i64 %sel 337*9880d681SAndroid Build Coastguard Worker} 338*9880d681SAndroid Build Coastguard Worker 339*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: select_ororand 340*9880d681SAndroid Build Coastguard Workerdefine i32 @select_ororand(i32 %w0, i32 %w1, i32 %w2, i32 %w3) { 341*9880d681SAndroid Build Coastguard Worker; CHECK: cmp w3, #4 342*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ccmp w2, #2, #0, gt 343*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ccmp w1, #13, #2, ge 344*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ccmp w0, #0, #4, ls 345*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: csel w0, w3, wzr, eq 346*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret 347*9880d681SAndroid Build Coastguard Worker %c0 = icmp eq i32 %w0, 0 348*9880d681SAndroid Build Coastguard Worker %c1 = icmp ugt i32 %w1, 13 349*9880d681SAndroid Build Coastguard Worker %c2 = icmp slt i32 %w2, 2 350*9880d681SAndroid Build Coastguard Worker %c4 = icmp sgt i32 %w3, 4 351*9880d681SAndroid Build Coastguard Worker %or = or i1 %c0, %c1 352*9880d681SAndroid Build Coastguard Worker %and = and i1 %c2, %c4 353*9880d681SAndroid Build Coastguard Worker %or1 = or i1 %or, %and 354*9880d681SAndroid Build Coastguard Worker %sel = select i1 %or1, i32 %w3, i32 0 355*9880d681SAndroid Build Coastguard Worker ret i32 %sel 356*9880d681SAndroid Build Coastguard Worker} 357*9880d681SAndroid Build Coastguard Worker 358*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: select_andor 359*9880d681SAndroid Build Coastguard Workerdefine i32 @select_andor(i32 %v1, i32 %v2, i32 %v3) { 360*9880d681SAndroid Build Coastguard Worker; CHECK: cmp w1, w2 361*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ccmp w0, #0, #4, lt 362*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ccmp w0, w1, #0, eq 363*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: csel w0, w0, w1, eq 364*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret 365*9880d681SAndroid Build Coastguard Worker %c0 = icmp eq i32 %v1, %v2 366*9880d681SAndroid Build Coastguard Worker %c1 = icmp sge i32 %v2, %v3 367*9880d681SAndroid Build Coastguard Worker %c2 = icmp eq i32 %v1, 0 368*9880d681SAndroid Build Coastguard Worker %or = or i1 %c2, %c1 369*9880d681SAndroid Build Coastguard Worker %and = and i1 %or, %c0 370*9880d681SAndroid Build Coastguard Worker %sel = select i1 %and, i32 %v1, i32 %v2 371*9880d681SAndroid Build Coastguard Worker ret i32 %sel 372*9880d681SAndroid Build Coastguard Worker} 373*9880d681SAndroid Build Coastguard Worker 374*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: select_noccmp1 375*9880d681SAndroid Build Coastguard Workerdefine i64 @select_noccmp1(i64 %v1, i64 %v2, i64 %v3, i64 %r) { 376*9880d681SAndroid Build Coastguard Worker; CHECK: cmp x0, #0 377*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: cset [[REG0:w[0-9]+]], lt 378*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: cmp x0, #13 379*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: ccmp 380*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: cset [[REG1:w[0-9]+]], gt 381*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: cmp x2, #2 382*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: cset [[REG2:w[0-9]+]], lt 383*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: cmp x2, #4 384*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: cset [[REG3:w[0-9]+]], gt 385*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: and [[REG4:w[0-9]+]], [[REG0]], [[REG1]] 386*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: and [[REG5:w[0-9]+]], [[REG2]], [[REG3]] 387*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: orr [[REG6:w[0-9]+]], [[REG4]], [[REG5]] 388*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: cmp [[REG6]], #0 389*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: csel x0, xzr, x3, ne 390*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret 391*9880d681SAndroid Build Coastguard Worker %c0 = icmp slt i64 %v1, 0 392*9880d681SAndroid Build Coastguard Worker %c1 = icmp sgt i64 %v1, 13 393*9880d681SAndroid Build Coastguard Worker %c2 = icmp slt i64 %v3, 2 394*9880d681SAndroid Build Coastguard Worker %c4 = icmp sgt i64 %v3, 4 395*9880d681SAndroid Build Coastguard Worker %and0 = and i1 %c0, %c1 396*9880d681SAndroid Build Coastguard Worker %and1 = and i1 %c2, %c4 397*9880d681SAndroid Build Coastguard Worker %or = or i1 %and0, %and1 398*9880d681SAndroid Build Coastguard Worker %sel = select i1 %or, i64 0, i64 %r 399*9880d681SAndroid Build Coastguard Worker ret i64 %sel 400*9880d681SAndroid Build Coastguard Worker} 401*9880d681SAndroid Build Coastguard Worker 402*9880d681SAndroid Build Coastguard Worker@g = global i32 0 403*9880d681SAndroid Build Coastguard Worker 404*9880d681SAndroid Build Coastguard Worker; Should not use ccmp if we have to compute the or expression in an integer 405*9880d681SAndroid Build Coastguard Worker; register anyway because of other users. 406*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: select_noccmp2 407*9880d681SAndroid Build Coastguard Workerdefine i64 @select_noccmp2(i64 %v1, i64 %v2, i64 %v3, i64 %r) { 408*9880d681SAndroid Build Coastguard Worker; CHECK: cmp x0, #0 409*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: cset [[REG0:w[0-9]+]], lt 410*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: ccmp 411*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: cmp x0, #13 412*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: cset [[REG1:w[0-9]+]], gt 413*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: orr [[REG2:w[0-9]+]], [[REG0]], [[REG1]] 414*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: cmp [[REG2]], #0 415*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: csel x0, xzr, x3, ne 416*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: sbfx [[REG3:w[0-9]+]], [[REG2]], #0, #1 417*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: adrp x[[REGN4:[0-9]+]], _g@PAGE 418*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: str [[REG3]], [x[[REGN4]], _g@PAGEOFF] 419*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret 420*9880d681SAndroid Build Coastguard Worker %c0 = icmp slt i64 %v1, 0 421*9880d681SAndroid Build Coastguard Worker %c1 = icmp sgt i64 %v1, 13 422*9880d681SAndroid Build Coastguard Worker %or = or i1 %c0, %c1 423*9880d681SAndroid Build Coastguard Worker %sel = select i1 %or, i64 0, i64 %r 424*9880d681SAndroid Build Coastguard Worker %ext = sext i1 %or to i32 425*9880d681SAndroid Build Coastguard Worker store volatile i32 %ext, i32* @g 426*9880d681SAndroid Build Coastguard Worker ret i64 %sel 427*9880d681SAndroid Build Coastguard Worker} 428*9880d681SAndroid Build Coastguard Worker 429*9880d681SAndroid Build Coastguard Worker; The following is not possible to implement with a single cmp;ccmp;csel 430*9880d681SAndroid Build Coastguard Worker; sequence. 431*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: select_noccmp3 432*9880d681SAndroid Build Coastguard Workerdefine i32 @select_noccmp3(i32 %v0, i32 %v1, i32 %v2) { 433*9880d681SAndroid Build Coastguard Worker %c0 = icmp slt i32 %v0, 0 434*9880d681SAndroid Build Coastguard Worker %c1 = icmp sgt i32 %v0, 13 435*9880d681SAndroid Build Coastguard Worker %c2 = icmp slt i32 %v0, 22 436*9880d681SAndroid Build Coastguard Worker %c3 = icmp sgt i32 %v0, 44 437*9880d681SAndroid Build Coastguard Worker %c4 = icmp eq i32 %v0, 99 438*9880d681SAndroid Build Coastguard Worker %c5 = icmp eq i32 %v0, 77 439*9880d681SAndroid Build Coastguard Worker %or0 = or i1 %c0, %c1 440*9880d681SAndroid Build Coastguard Worker %or1 = or i1 %c2, %c3 441*9880d681SAndroid Build Coastguard Worker %and0 = and i1 %or0, %or1 442*9880d681SAndroid Build Coastguard Worker %or2 = or i1 %c4, %c5 443*9880d681SAndroid Build Coastguard Worker %and1 = and i1 %and0, %or2 444*9880d681SAndroid Build Coastguard Worker %sel = select i1 %and1, i32 %v1, i32 %v2 445*9880d681SAndroid Build Coastguard Worker ret i32 %sel 446*9880d681SAndroid Build Coastguard Worker} 447*9880d681SAndroid Build Coastguard Worker 448*9880d681SAndroid Build Coastguard Worker; Test the IR CCs that expand to two cond codes. 449*9880d681SAndroid Build Coastguard Worker 450*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: select_and_olt_one: 451*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: ; BB#0: 452*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: fcmp d0, d1 453*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: fccmp d2, d3, #4, mi 454*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: fccmp d2, d3, #1, ne 455*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: csel w0, w0, w1, vc 456*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret 457*9880d681SAndroid Build Coastguard Workerdefine i32 @select_and_olt_one(double %v0, double %v1, double %v2, double %v3, i32 %a, i32 %b) #0 { 458*9880d681SAndroid Build Coastguard Worker %c0 = fcmp olt double %v0, %v1 459*9880d681SAndroid Build Coastguard Worker %c1 = fcmp one double %v2, %v3 460*9880d681SAndroid Build Coastguard Worker %cr = and i1 %c1, %c0 461*9880d681SAndroid Build Coastguard Worker %sel = select i1 %cr, i32 %a, i32 %b 462*9880d681SAndroid Build Coastguard Worker ret i32 %sel 463*9880d681SAndroid Build Coastguard Worker} 464*9880d681SAndroid Build Coastguard Worker 465*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: select_and_one_olt: 466*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: ; BB#0: 467*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: fcmp d0, d1 468*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: fccmp d0, d1, #1, ne 469*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: fccmp d2, d3, #0, vc 470*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: csel w0, w0, w1, mi 471*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret 472*9880d681SAndroid Build Coastguard Workerdefine i32 @select_and_one_olt(double %v0, double %v1, double %v2, double %v3, i32 %a, i32 %b) #0 { 473*9880d681SAndroid Build Coastguard Worker %c0 = fcmp one double %v0, %v1 474*9880d681SAndroid Build Coastguard Worker %c1 = fcmp olt double %v2, %v3 475*9880d681SAndroid Build Coastguard Worker %cr = and i1 %c1, %c0 476*9880d681SAndroid Build Coastguard Worker %sel = select i1 %cr, i32 %a, i32 %b 477*9880d681SAndroid Build Coastguard Worker ret i32 %sel 478*9880d681SAndroid Build Coastguard Worker} 479*9880d681SAndroid Build Coastguard Worker 480*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: select_and_olt_ueq: 481*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: ; BB#0: 482*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: fcmp d0, d1 483*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: fccmp d2, d3, #0, mi 484*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: fccmp d2, d3, #8, le 485*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: csel w0, w0, w1, pl 486*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret 487*9880d681SAndroid Build Coastguard Workerdefine i32 @select_and_olt_ueq(double %v0, double %v1, double %v2, double %v3, i32 %a, i32 %b) #0 { 488*9880d681SAndroid Build Coastguard Worker %c0 = fcmp olt double %v0, %v1 489*9880d681SAndroid Build Coastguard Worker %c1 = fcmp ueq double %v2, %v3 490*9880d681SAndroid Build Coastguard Worker %cr = and i1 %c1, %c0 491*9880d681SAndroid Build Coastguard Worker %sel = select i1 %cr, i32 %a, i32 %b 492*9880d681SAndroid Build Coastguard Worker ret i32 %sel 493*9880d681SAndroid Build Coastguard Worker} 494*9880d681SAndroid Build Coastguard Worker 495*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: select_and_ueq_olt: 496*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: ; BB#0: 497*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: fcmp d0, d1 498*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: fccmp d0, d1, #8, le 499*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: fccmp d2, d3, #0, pl 500*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: csel w0, w0, w1, mi 501*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret 502*9880d681SAndroid Build Coastguard Workerdefine i32 @select_and_ueq_olt(double %v0, double %v1, double %v2, double %v3, i32 %a, i32 %b) #0 { 503*9880d681SAndroid Build Coastguard Worker %c0 = fcmp ueq double %v0, %v1 504*9880d681SAndroid Build Coastguard Worker %c1 = fcmp olt double %v2, %v3 505*9880d681SAndroid Build Coastguard Worker %cr = and i1 %c1, %c0 506*9880d681SAndroid Build Coastguard Worker %sel = select i1 %cr, i32 %a, i32 %b 507*9880d681SAndroid Build Coastguard Worker ret i32 %sel 508*9880d681SAndroid Build Coastguard Worker} 509*9880d681SAndroid Build Coastguard Worker 510*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: select_or_olt_one: 511*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: ; BB#0: 512*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: fcmp d0, d1 513*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: fccmp d2, d3, #0, pl 514*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: fccmp d2, d3, #8, le 515*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: csel w0, w0, w1, mi 516*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret 517*9880d681SAndroid Build Coastguard Workerdefine i32 @select_or_olt_one(double %v0, double %v1, double %v2, double %v3, i32 %a, i32 %b) #0 { 518*9880d681SAndroid Build Coastguard Worker %c0 = fcmp olt double %v0, %v1 519*9880d681SAndroid Build Coastguard Worker %c1 = fcmp one double %v2, %v3 520*9880d681SAndroid Build Coastguard Worker %cr = or i1 %c1, %c0 521*9880d681SAndroid Build Coastguard Worker %sel = select i1 %cr, i32 %a, i32 %b 522*9880d681SAndroid Build Coastguard Worker ret i32 %sel 523*9880d681SAndroid Build Coastguard Worker} 524*9880d681SAndroid Build Coastguard Worker 525*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: select_or_one_olt: 526*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: ; BB#0: 527*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: fcmp d0, d1 528*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: fccmp d0, d1, #1, ne 529*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: fccmp d2, d3, #8, vs 530*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: csel w0, w0, w1, mi 531*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret 532*9880d681SAndroid Build Coastguard Workerdefine i32 @select_or_one_olt(double %v0, double %v1, double %v2, double %v3, i32 %a, i32 %b) #0 { 533*9880d681SAndroid Build Coastguard Worker %c0 = fcmp one double %v0, %v1 534*9880d681SAndroid Build Coastguard Worker %c1 = fcmp olt double %v2, %v3 535*9880d681SAndroid Build Coastguard Worker %cr = or i1 %c1, %c0 536*9880d681SAndroid Build Coastguard Worker %sel = select i1 %cr, i32 %a, i32 %b 537*9880d681SAndroid Build Coastguard Worker ret i32 %sel 538*9880d681SAndroid Build Coastguard Worker} 539*9880d681SAndroid Build Coastguard Worker 540*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: select_or_olt_ueq: 541*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: ; BB#0: 542*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: fcmp d0, d1 543*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: fccmp d2, d3, #4, pl 544*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: fccmp d2, d3, #1, ne 545*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: csel w0, w0, w1, vs 546*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret 547*9880d681SAndroid Build Coastguard Workerdefine i32 @select_or_olt_ueq(double %v0, double %v1, double %v2, double %v3, i32 %a, i32 %b) #0 { 548*9880d681SAndroid Build Coastguard Worker %c0 = fcmp olt double %v0, %v1 549*9880d681SAndroid Build Coastguard Worker %c1 = fcmp ueq double %v2, %v3 550*9880d681SAndroid Build Coastguard Worker %cr = or i1 %c1, %c0 551*9880d681SAndroid Build Coastguard Worker %sel = select i1 %cr, i32 %a, i32 %b 552*9880d681SAndroid Build Coastguard Worker ret i32 %sel 553*9880d681SAndroid Build Coastguard Worker} 554*9880d681SAndroid Build Coastguard Worker 555*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: select_or_ueq_olt: 556*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: ; BB#0: 557*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: fcmp d0, d1 558*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: fccmp d0, d1, #8, le 559*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: fccmp d2, d3, #8, mi 560*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: csel w0, w0, w1, mi 561*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret 562*9880d681SAndroid Build Coastguard Workerdefine i32 @select_or_ueq_olt(double %v0, double %v1, double %v2, double %v3, i32 %a, i32 %b) #0 { 563*9880d681SAndroid Build Coastguard Worker %c0 = fcmp ueq double %v0, %v1 564*9880d681SAndroid Build Coastguard Worker %c1 = fcmp olt double %v2, %v3 565*9880d681SAndroid Build Coastguard Worker %cr = or i1 %c1, %c0 566*9880d681SAndroid Build Coastguard Worker %sel = select i1 %cr, i32 %a, i32 %b 567*9880d681SAndroid Build Coastguard Worker ret i32 %sel 568*9880d681SAndroid Build Coastguard Worker} 569*9880d681SAndroid Build Coastguard Worker 570*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: select_or_olt_ogt_ueq: 571*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: ; BB#0: 572*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: fcmp d0, d1 573*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: fccmp d2, d3, #0, pl 574*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: fccmp d4, d5, #4, le 575*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: fccmp d4, d5, #1, ne 576*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: csel w0, w0, w1, vs 577*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret 578*9880d681SAndroid Build Coastguard Workerdefine i32 @select_or_olt_ogt_ueq(double %v0, double %v1, double %v2, double %v3, double %v4, double %v5, i32 %a, i32 %b) #0 { 579*9880d681SAndroid Build Coastguard Worker %c0 = fcmp olt double %v0, %v1 580*9880d681SAndroid Build Coastguard Worker %c1 = fcmp ogt double %v2, %v3 581*9880d681SAndroid Build Coastguard Worker %c2 = fcmp ueq double %v4, %v5 582*9880d681SAndroid Build Coastguard Worker %c3 = or i1 %c1, %c0 583*9880d681SAndroid Build Coastguard Worker %cr = or i1 %c2, %c3 584*9880d681SAndroid Build Coastguard Worker %sel = select i1 %cr, i32 %a, i32 %b 585*9880d681SAndroid Build Coastguard Worker ret i32 %sel 586*9880d681SAndroid Build Coastguard Worker} 587*9880d681SAndroid Build Coastguard Worker 588*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: select_or_olt_ueq_ogt: 589*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: ; BB#0: 590*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: fcmp d0, d1 591*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: fccmp d2, d3, #4, pl 592*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: fccmp d2, d3, #1, ne 593*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: fccmp d4, d5, #0, vc 594*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: csel w0, w0, w1, gt 595*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret 596*9880d681SAndroid Build Coastguard Workerdefine i32 @select_or_olt_ueq_ogt(double %v0, double %v1, double %v2, double %v3, double %v4, double %v5, i32 %a, i32 %b) #0 { 597*9880d681SAndroid Build Coastguard Worker %c0 = fcmp olt double %v0, %v1 598*9880d681SAndroid Build Coastguard Worker %c1 = fcmp ueq double %v2, %v3 599*9880d681SAndroid Build Coastguard Worker %c2 = fcmp ogt double %v4, %v5 600*9880d681SAndroid Build Coastguard Worker %c3 = or i1 %c1, %c0 601*9880d681SAndroid Build Coastguard Worker %cr = or i1 %c2, %c3 602*9880d681SAndroid Build Coastguard Worker %sel = select i1 %cr, i32 %a, i32 %b 603*9880d681SAndroid Build Coastguard Worker ret i32 %sel 604*9880d681SAndroid Build Coastguard Worker} 605*9880d681SAndroid Build Coastguard Worker 606*9880d681SAndroid Build Coastguard Worker; Verify that we correctly promote f16. 607*9880d681SAndroid Build Coastguard Worker 608*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: half_select_and_olt_oge: 609*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: ; BB#0: 610*9880d681SAndroid Build Coastguard Worker; CHECK-DAG: fcvt [[S0:s[0-9]+]], h0 611*9880d681SAndroid Build Coastguard Worker; CHECK-DAG: fcvt [[S1:s[0-9]+]], h1 612*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: fcmp [[S0]], [[S1]] 613*9880d681SAndroid Build Coastguard Worker; CHECK-DAG: fcvt [[S2:s[0-9]+]], h2 614*9880d681SAndroid Build Coastguard Worker; CHECK-DAG: fcvt [[S3:s[0-9]+]], h3 615*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: fccmp [[S2]], [[S3]], #8, mi 616*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: csel w0, w0, w1, ge 617*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret 618*9880d681SAndroid Build Coastguard Workerdefine i32 @half_select_and_olt_oge(half %v0, half %v1, half %v2, half %v3, i32 %a, i32 %b) #0 { 619*9880d681SAndroid Build Coastguard Worker %c0 = fcmp olt half %v0, %v1 620*9880d681SAndroid Build Coastguard Worker %c1 = fcmp oge half %v2, %v3 621*9880d681SAndroid Build Coastguard Worker %cr = and i1 %c1, %c0 622*9880d681SAndroid Build Coastguard Worker %sel = select i1 %cr, i32 %a, i32 %b 623*9880d681SAndroid Build Coastguard Worker ret i32 %sel 624*9880d681SAndroid Build Coastguard Worker} 625*9880d681SAndroid Build Coastguard Worker 626*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: half_select_and_olt_one: 627*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: ; BB#0: 628*9880d681SAndroid Build Coastguard Worker; CHECK-DAG: fcvt [[S0:s[0-9]+]], h0 629*9880d681SAndroid Build Coastguard Worker; CHECK-DAG: fcvt [[S1:s[0-9]+]], h1 630*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: fcmp [[S0]], [[S1]] 631*9880d681SAndroid Build Coastguard Worker; CHECK-DAG: fcvt [[S2:s[0-9]+]], h2 632*9880d681SAndroid Build Coastguard Worker; CHECK-DAG: fcvt [[S3:s[0-9]+]], h3 633*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: fccmp [[S2]], [[S3]], #4, mi 634*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: fccmp [[S2]], [[S3]], #1, ne 635*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: csel w0, w0, w1, vc 636*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret 637*9880d681SAndroid Build Coastguard Workerdefine i32 @half_select_and_olt_one(half %v0, half %v1, half %v2, half %v3, i32 %a, i32 %b) #0 { 638*9880d681SAndroid Build Coastguard Worker %c0 = fcmp olt half %v0, %v1 639*9880d681SAndroid Build Coastguard Worker %c1 = fcmp one half %v2, %v3 640*9880d681SAndroid Build Coastguard Worker %cr = and i1 %c1, %c0 641*9880d681SAndroid Build Coastguard Worker %sel = select i1 %cr, i32 %a, i32 %b 642*9880d681SAndroid Build Coastguard Worker ret i32 %sel 643*9880d681SAndroid Build Coastguard Worker} 644*9880d681SAndroid Build Coastguard Worker 645*9880d681SAndroid Build Coastguard Worker; Also verify that we don't try to generate f128 FCCMPs, using RT calls instead. 646*9880d681SAndroid Build Coastguard Worker 647*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f128_select_and_olt_oge: 648*9880d681SAndroid Build Coastguard Worker; CHECK: bl ___lttf2 649*9880d681SAndroid Build Coastguard Worker; CHECK: bl ___getf2 650*9880d681SAndroid Build Coastguard Workerdefine i32 @f128_select_and_olt_oge(fp128 %v0, fp128 %v1, fp128 %v2, fp128 %v3, i32 %a, i32 %b) #0 { 651*9880d681SAndroid Build Coastguard Worker %c0 = fcmp olt fp128 %v0, %v1 652*9880d681SAndroid Build Coastguard Worker %c1 = fcmp oge fp128 %v2, %v3 653*9880d681SAndroid Build Coastguard Worker %cr = and i1 %c1, %c0 654*9880d681SAndroid Build Coastguard Worker %sel = select i1 %cr, i32 %a, i32 %b 655*9880d681SAndroid Build Coastguard Worker ret i32 %sel 656*9880d681SAndroid Build Coastguard Worker} 657*9880d681SAndroid Build Coastguard Worker 658*9880d681SAndroid Build Coastguard Workerattributes #0 = { nounwind } 659