1*9880d681SAndroid Build Coastguard Worker; RUN: llc < %s -mtriple=lanai | FileCheck %s 2*9880d681SAndroid Build Coastguard Worker 3*9880d681SAndroid Build Coastguard Workerdefine i32 @f(i32 inreg %a, i32 inreg %b) nounwind ssp { 4*9880d681SAndroid Build Coastguard Workerentry: 5*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f: 6*9880d681SAndroid Build Coastguard Worker; CHECK: sub.f %r6, %r7, [[IN:%.*]] 7*9880d681SAndroid Build Coastguard Worker; CHECK: sel.gt [[IN]], %r0, %rv 8*9880d681SAndroid Build Coastguard Worker %cmp = icmp sgt i32 %a, %b 9*9880d681SAndroid Build Coastguard Worker %sub = sub nsw i32 %a, %b 10*9880d681SAndroid Build Coastguard Worker %sub. = select i1 %cmp, i32 %sub, i32 0 11*9880d681SAndroid Build Coastguard Worker ret i32 %sub. 12*9880d681SAndroid Build Coastguard Worker} 13*9880d681SAndroid Build Coastguard Worker 14*9880d681SAndroid Build Coastguard Workerdefine i32 @g(i32 inreg %a, i32 inreg %b) nounwind ssp { 15*9880d681SAndroid Build Coastguard Workerentry: 16*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: g: 17*9880d681SAndroid Build Coastguard Worker; CHECK: sub.f %r7, %r6, [[IN:%.*]] 18*9880d681SAndroid Build Coastguard Worker; CHECK: sel.lt [[IN]], %r0, %rv 19*9880d681SAndroid Build Coastguard Worker %cmp = icmp slt i32 %a, %b 20*9880d681SAndroid Build Coastguard Worker %sub = sub nsw i32 %b, %a 21*9880d681SAndroid Build Coastguard Worker %sub. = select i1 %cmp, i32 %sub, i32 0 22*9880d681SAndroid Build Coastguard Worker ret i32 %sub. 23*9880d681SAndroid Build Coastguard Worker} 24*9880d681SAndroid Build Coastguard Worker 25*9880d681SAndroid Build Coastguard Workerdefine i32 @h(i32 inreg %a, i32 inreg %b) nounwind ssp { 26*9880d681SAndroid Build Coastguard Workerentry: 27*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: h: 28*9880d681SAndroid Build Coastguard Worker; CHECK: sub.f %r6, 0x3, [[IN:%.*]] 29*9880d681SAndroid Build Coastguard Worker; CHECK: sel.gt [[IN]], %r7, %rv 30*9880d681SAndroid Build Coastguard Worker %cmp = icmp sgt i32 %a, 3 31*9880d681SAndroid Build Coastguard Worker %sub = sub nsw i32 %a, 3 32*9880d681SAndroid Build Coastguard Worker %sub. = select i1 %cmp, i32 %sub, i32 %b 33*9880d681SAndroid Build Coastguard Worker ret i32 %sub. 34*9880d681SAndroid Build Coastguard Worker} 35*9880d681SAndroid Build Coastguard Worker 36*9880d681SAndroid Build Coastguard Workerdefine i32 @i(i32 inreg %a, i32 inreg %b) nounwind readnone ssp { 37*9880d681SAndroid Build Coastguard Workerentry: 38*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: i: 39*9880d681SAndroid Build Coastguard Worker; CHECK: sub.f %r7, %r6, [[IN:%.*]] 40*9880d681SAndroid Build Coastguard Worker; CHECK: sel.ult [[IN]], %r0, %rv 41*9880d681SAndroid Build Coastguard Worker %cmp = icmp ult i32 %a, %b 42*9880d681SAndroid Build Coastguard Worker %sub = sub i32 %b, %a 43*9880d681SAndroid Build Coastguard Worker %sub. = select i1 %cmp, i32 %sub, i32 0 44*9880d681SAndroid Build Coastguard Worker ret i32 %sub. 45*9880d681SAndroid Build Coastguard Worker} 46*9880d681SAndroid Build Coastguard Worker; If SR is live-out, we can't remove cmp if there exists a swapped sub. 47*9880d681SAndroid Build Coastguard Workerdefine i32 @j(i32 inreg %a, i32 inreg %b) nounwind { 48*9880d681SAndroid Build Coastguard Workerentry: 49*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: j: 50*9880d681SAndroid Build Coastguard Worker; CHECK: sub.f %r7, %r6, %r0 51*9880d681SAndroid Build Coastguard Worker; CHECK: sub %r6, %r7, %rv 52*9880d681SAndroid Build Coastguard Worker %cmp = icmp eq i32 %b, %a 53*9880d681SAndroid Build Coastguard Worker %sub = sub nsw i32 %a, %b 54*9880d681SAndroid Build Coastguard Worker br i1 %cmp, label %if.then, label %if.else 55*9880d681SAndroid Build Coastguard Worker 56*9880d681SAndroid Build Coastguard Workerif.then: 57*9880d681SAndroid Build Coastguard Worker %cmp2 = icmp sgt i32 %b, %a 58*9880d681SAndroid Build Coastguard Worker %sel = select i1 %cmp2, i32 %sub, i32 %a 59*9880d681SAndroid Build Coastguard Worker ret i32 %sel 60*9880d681SAndroid Build Coastguard Worker 61*9880d681SAndroid Build Coastguard Workerif.else: 62*9880d681SAndroid Build Coastguard Worker ret i32 %sub 63*9880d681SAndroid Build Coastguard Worker} 64*9880d681SAndroid Build Coastguard Worker 65*9880d681SAndroid Build Coastguard Workerdeclare void @abort() 66*9880d681SAndroid Build Coastguard Workerdeclare void @exit(i32) 67*9880d681SAndroid Build Coastguard Worker@t = common global i32 0 68*9880d681SAndroid Build Coastguard Worker 69*9880d681SAndroid Build Coastguard Worker; If the comparison uses the C bit (signed overflow/underflow), we can't 70*9880d681SAndroid Build Coastguard Worker; omit the comparison. 71*9880d681SAndroid Build Coastguard Workerdefine i32 @cmp_ult0(i32 inreg %a, i32 inreg %b, i32 inreg %x, i32 inreg %y) { 72*9880d681SAndroid Build Coastguard Workerentry: 73*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: cmp_ult0 74*9880d681SAndroid Build Coastguard Worker; CHECK: sub {{.*}}, 0x11, [[IN:%.*]] 75*9880d681SAndroid Build Coastguard Worker; CHECK: sub.f [[IN]], 0x0, %r0 76*9880d681SAndroid Build Coastguard Worker %load = load i32, i32* @t, align 4 77*9880d681SAndroid Build Coastguard Worker %sub = sub i32 %load, 17 78*9880d681SAndroid Build Coastguard Worker %cmp = icmp ult i32 %sub, 0 79*9880d681SAndroid Build Coastguard Worker br i1 %cmp, label %if.then, label %if.else 80*9880d681SAndroid Build Coastguard Worker 81*9880d681SAndroid Build Coastguard Workerif.then: 82*9880d681SAndroid Build Coastguard Worker call void @abort() 83*9880d681SAndroid Build Coastguard Worker unreachable 84*9880d681SAndroid Build Coastguard Worker 85*9880d681SAndroid Build Coastguard Workerif.else: 86*9880d681SAndroid Build Coastguard Worker call void @exit(i32 0) 87*9880d681SAndroid Build Coastguard Worker unreachable 88*9880d681SAndroid Build Coastguard Worker} 89*9880d681SAndroid Build Coastguard Worker 90*9880d681SAndroid Build Coastguard Worker; Same for the V bit. 91*9880d681SAndroid Build Coastguard Worker; TODO: add test that exercises V bit individually (VC/VS). 92*9880d681SAndroid Build Coastguard Workerdefine i32 @cmp_gt0(i32 inreg %a, i32 inreg %b, i32 inreg %x, i32 inreg %y) { 93*9880d681SAndroid Build Coastguard Workerentry: 94*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: cmp_gt0 95*9880d681SAndroid Build Coastguard Worker; CHECK: sub {{.*}}, 0x11, [[IN:%.*]] 96*9880d681SAndroid Build Coastguard Worker; CHECK: sub.f [[IN]], 0x1, %r0 97*9880d681SAndroid Build Coastguard Worker %load = load i32, i32* @t, align 4 98*9880d681SAndroid Build Coastguard Worker %sub = sub i32 %load, 17 99*9880d681SAndroid Build Coastguard Worker %cmp = icmp sgt i32 %sub, 0 100*9880d681SAndroid Build Coastguard Worker br i1 %cmp, label %if.then, label %if.else 101*9880d681SAndroid Build Coastguard Worker 102*9880d681SAndroid Build Coastguard Workerif.then: 103*9880d681SAndroid Build Coastguard Worker call void @abort() 104*9880d681SAndroid Build Coastguard Worker unreachable 105*9880d681SAndroid Build Coastguard Worker 106*9880d681SAndroid Build Coastguard Workerif.else: 107*9880d681SAndroid Build Coastguard Worker call void @exit(i32 0) 108*9880d681SAndroid Build Coastguard Worker unreachable 109*9880d681SAndroid Build Coastguard Worker} 110