1*9880d681SAndroid Build Coastguard Worker; Test 32-bit signed comparison in which the second operand is a variable. 2*9880d681SAndroid Build Coastguard Worker; 3*9880d681SAndroid Build Coastguard Worker; RUN: llc < %s -mtriple=s390x-linux-gnu | FileCheck %s 4*9880d681SAndroid Build Coastguard Worker 5*9880d681SAndroid Build Coastguard Workerdeclare i32 @foo() 6*9880d681SAndroid Build Coastguard Worker 7*9880d681SAndroid Build Coastguard Worker; Check register comparison. 8*9880d681SAndroid Build Coastguard Workerdefine double @f1(double %a, double %b, i32 %i1, i32 %i2) { 9*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f1: 10*9880d681SAndroid Build Coastguard Worker; CHECK: crbl %r2, %r3, 0(%r14) 11*9880d681SAndroid Build Coastguard Worker; CHECK: ldr %f0, %f2 12*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14 13*9880d681SAndroid Build Coastguard Worker %cond = icmp slt i32 %i1, %i2 14*9880d681SAndroid Build Coastguard Worker %res = select i1 %cond, double %a, double %b 15*9880d681SAndroid Build Coastguard Worker ret double %res 16*9880d681SAndroid Build Coastguard Worker} 17*9880d681SAndroid Build Coastguard Worker 18*9880d681SAndroid Build Coastguard Worker; Check the low end of the C range. 19*9880d681SAndroid Build Coastguard Workerdefine double @f2(double %a, double %b, i32 %i1, i32 *%ptr) { 20*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f2: 21*9880d681SAndroid Build Coastguard Worker; CHECK: c %r2, 0(%r3) 22*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: blr %r14 23*9880d681SAndroid Build Coastguard Worker; CHECK: ldr %f0, %f2 24*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14 25*9880d681SAndroid Build Coastguard Worker %i2 = load i32 , i32 *%ptr 26*9880d681SAndroid Build Coastguard Worker %cond = icmp slt i32 %i1, %i2 27*9880d681SAndroid Build Coastguard Worker %res = select i1 %cond, double %a, double %b 28*9880d681SAndroid Build Coastguard Worker ret double %res 29*9880d681SAndroid Build Coastguard Worker} 30*9880d681SAndroid Build Coastguard Worker 31*9880d681SAndroid Build Coastguard Worker; Check the high end of the aligned C range. 32*9880d681SAndroid Build Coastguard Workerdefine double @f3(double %a, double %b, i32 %i1, i32 *%base) { 33*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f3: 34*9880d681SAndroid Build Coastguard Worker; CHECK: c %r2, 4092(%r3) 35*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: blr %r14 36*9880d681SAndroid Build Coastguard Worker; CHECK: ldr %f0, %f2 37*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14 38*9880d681SAndroid Build Coastguard Worker %ptr = getelementptr i32, i32 *%base, i64 1023 39*9880d681SAndroid Build Coastguard Worker %i2 = load i32 , i32 *%ptr 40*9880d681SAndroid Build Coastguard Worker %cond = icmp slt i32 %i1, %i2 41*9880d681SAndroid Build Coastguard Worker %res = select i1 %cond, double %a, double %b 42*9880d681SAndroid Build Coastguard Worker ret double %res 43*9880d681SAndroid Build Coastguard Worker} 44*9880d681SAndroid Build Coastguard Worker 45*9880d681SAndroid Build Coastguard Worker; Check the next word up, which should use CY instead of C. 46*9880d681SAndroid Build Coastguard Workerdefine double @f4(double %a, double %b, i32 %i1, i32 *%base) { 47*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f4: 48*9880d681SAndroid Build Coastguard Worker; CHECK: cy %r2, 4096(%r3) 49*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: blr %r14 50*9880d681SAndroid Build Coastguard Worker; CHECK: ldr %f0, %f2 51*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14 52*9880d681SAndroid Build Coastguard Worker %ptr = getelementptr i32, i32 *%base, i64 1024 53*9880d681SAndroid Build Coastguard Worker %i2 = load i32 , i32 *%ptr 54*9880d681SAndroid Build Coastguard Worker %cond = icmp slt i32 %i1, %i2 55*9880d681SAndroid Build Coastguard Worker %res = select i1 %cond, double %a, double %b 56*9880d681SAndroid Build Coastguard Worker ret double %res 57*9880d681SAndroid Build Coastguard Worker} 58*9880d681SAndroid Build Coastguard Worker 59*9880d681SAndroid Build Coastguard Worker; Check the high end of the aligned CY range. 60*9880d681SAndroid Build Coastguard Workerdefine double @f5(double %a, double %b, i32 %i1, i32 *%base) { 61*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f5: 62*9880d681SAndroid Build Coastguard Worker; CHECK: cy %r2, 524284(%r3) 63*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: blr %r14 64*9880d681SAndroid Build Coastguard Worker; CHECK: ldr %f0, %f2 65*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14 66*9880d681SAndroid Build Coastguard Worker %ptr = getelementptr i32, i32 *%base, i64 131071 67*9880d681SAndroid Build Coastguard Worker %i2 = load i32 , i32 *%ptr 68*9880d681SAndroid Build Coastguard Worker %cond = icmp slt i32 %i1, %i2 69*9880d681SAndroid Build Coastguard Worker %res = select i1 %cond, double %a, double %b 70*9880d681SAndroid Build Coastguard Worker ret double %res 71*9880d681SAndroid Build Coastguard Worker} 72*9880d681SAndroid Build Coastguard Worker 73*9880d681SAndroid Build Coastguard Worker; Check the next word up, which needs separate address logic. 74*9880d681SAndroid Build Coastguard Worker; Other sequences besides this one would be OK. 75*9880d681SAndroid Build Coastguard Workerdefine double @f6(double %a, double %b, i32 %i1, i32 *%base) { 76*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f6: 77*9880d681SAndroid Build Coastguard Worker; CHECK: agfi %r3, 524288 78*9880d681SAndroid Build Coastguard Worker; CHECK: c %r2, 0(%r3) 79*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: blr %r14 80*9880d681SAndroid Build Coastguard Worker; CHECK: ldr %f0, %f2 81*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14 82*9880d681SAndroid Build Coastguard Worker %ptr = getelementptr i32, i32 *%base, i64 131072 83*9880d681SAndroid Build Coastguard Worker %i2 = load i32 , i32 *%ptr 84*9880d681SAndroid Build Coastguard Worker %cond = icmp slt i32 %i1, %i2 85*9880d681SAndroid Build Coastguard Worker %res = select i1 %cond, double %a, double %b 86*9880d681SAndroid Build Coastguard Worker ret double %res 87*9880d681SAndroid Build Coastguard Worker} 88*9880d681SAndroid Build Coastguard Worker 89*9880d681SAndroid Build Coastguard Worker; Check the high end of the negative aligned CY range. 90*9880d681SAndroid Build Coastguard Workerdefine double @f7(double %a, double %b, i32 %i1, i32 *%base) { 91*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f7: 92*9880d681SAndroid Build Coastguard Worker; CHECK: cy %r2, -4(%r3) 93*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: blr %r14 94*9880d681SAndroid Build Coastguard Worker; CHECK: ldr %f0, %f2 95*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14 96*9880d681SAndroid Build Coastguard Worker %ptr = getelementptr i32, i32 *%base, i64 -1 97*9880d681SAndroid Build Coastguard Worker %i2 = load i32 , i32 *%ptr 98*9880d681SAndroid Build Coastguard Worker %cond = icmp slt i32 %i1, %i2 99*9880d681SAndroid Build Coastguard Worker %res = select i1 %cond, double %a, double %b 100*9880d681SAndroid Build Coastguard Worker ret double %res 101*9880d681SAndroid Build Coastguard Worker} 102*9880d681SAndroid Build Coastguard Worker 103*9880d681SAndroid Build Coastguard Worker; Check the low end of the CY range. 104*9880d681SAndroid Build Coastguard Workerdefine double @f8(double %a, double %b, i32 %i1, i32 *%base) { 105*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f8: 106*9880d681SAndroid Build Coastguard Worker; CHECK: cy %r2, -524288(%r3) 107*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: blr %r14 108*9880d681SAndroid Build Coastguard Worker; CHECK: ldr %f0, %f2 109*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14 110*9880d681SAndroid Build Coastguard Worker %ptr = getelementptr i32, i32 *%base, i64 -131072 111*9880d681SAndroid Build Coastguard Worker %i2 = load i32 , i32 *%ptr 112*9880d681SAndroid Build Coastguard Worker %cond = icmp slt i32 %i1, %i2 113*9880d681SAndroid Build Coastguard Worker %res = select i1 %cond, double %a, double %b 114*9880d681SAndroid Build Coastguard Worker ret double %res 115*9880d681SAndroid Build Coastguard Worker} 116*9880d681SAndroid Build Coastguard Worker 117*9880d681SAndroid Build Coastguard Worker; Check the next word down, which needs separate address logic. 118*9880d681SAndroid Build Coastguard Worker; Other sequences besides this one would be OK. 119*9880d681SAndroid Build Coastguard Workerdefine double @f9(double %a, double %b, i32 %i1, i32 *%base) { 120*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f9: 121*9880d681SAndroid Build Coastguard Worker; CHECK: agfi %r3, -524292 122*9880d681SAndroid Build Coastguard Worker; CHECK: c %r2, 0(%r3) 123*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: blr %r14 124*9880d681SAndroid Build Coastguard Worker; CHECK: ldr %f0, %f2 125*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14 126*9880d681SAndroid Build Coastguard Worker %ptr = getelementptr i32, i32 *%base, i64 -131073 127*9880d681SAndroid Build Coastguard Worker %i2 = load i32 , i32 *%ptr 128*9880d681SAndroid Build Coastguard Worker %cond = icmp slt i32 %i1, %i2 129*9880d681SAndroid Build Coastguard Worker %res = select i1 %cond, double %a, double %b 130*9880d681SAndroid Build Coastguard Worker ret double %res 131*9880d681SAndroid Build Coastguard Worker} 132*9880d681SAndroid Build Coastguard Worker 133*9880d681SAndroid Build Coastguard Worker; Check that C allows an index. 134*9880d681SAndroid Build Coastguard Workerdefine double @f10(double %a, double %b, i32 %i1, i64 %base, i64 %index) { 135*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f10: 136*9880d681SAndroid Build Coastguard Worker; CHECK: c %r2, 4092({{%r4,%r3|%r3,%r4}}) 137*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: blr %r14 138*9880d681SAndroid Build Coastguard Worker; CHECK: ldr %f0, %f2 139*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14 140*9880d681SAndroid Build Coastguard Worker %add1 = add i64 %base, %index 141*9880d681SAndroid Build Coastguard Worker %add2 = add i64 %add1, 4092 142*9880d681SAndroid Build Coastguard Worker %ptr = inttoptr i64 %add2 to i32 * 143*9880d681SAndroid Build Coastguard Worker %i2 = load i32 , i32 *%ptr 144*9880d681SAndroid Build Coastguard Worker %cond = icmp slt i32 %i1, %i2 145*9880d681SAndroid Build Coastguard Worker %res = select i1 %cond, double %a, double %b 146*9880d681SAndroid Build Coastguard Worker ret double %res 147*9880d681SAndroid Build Coastguard Worker} 148*9880d681SAndroid Build Coastguard Worker 149*9880d681SAndroid Build Coastguard Worker; Check that CY allows an index. 150*9880d681SAndroid Build Coastguard Workerdefine double @f11(double %a, double %b, i32 %i1, i64 %base, i64 %index) { 151*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f11: 152*9880d681SAndroid Build Coastguard Worker; CHECK: cy %r2, 4096({{%r4,%r3|%r3,%r4}}) 153*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: blr %r14 154*9880d681SAndroid Build Coastguard Worker; CHECK: ldr %f0, %f2 155*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14 156*9880d681SAndroid Build Coastguard Worker %add1 = add i64 %base, %index 157*9880d681SAndroid Build Coastguard Worker %add2 = add i64 %add1, 4096 158*9880d681SAndroid Build Coastguard Worker %ptr = inttoptr i64 %add2 to i32 * 159*9880d681SAndroid Build Coastguard Worker %i2 = load i32 , i32 *%ptr 160*9880d681SAndroid Build Coastguard Worker %cond = icmp slt i32 %i1, %i2 161*9880d681SAndroid Build Coastguard Worker %res = select i1 %cond, double %a, double %b 162*9880d681SAndroid Build Coastguard Worker ret double %res 163*9880d681SAndroid Build Coastguard Worker} 164*9880d681SAndroid Build Coastguard Worker 165*9880d681SAndroid Build Coastguard Worker; The first branch here got recreated by InsertBranch while splitting the 166*9880d681SAndroid Build Coastguard Worker; critical edge %entry->%while.body, which lost the kills information for CC. 167*9880d681SAndroid Build Coastguard Workerdefine void @f12(i32 %a, i32 %b) { 168*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f12: 169*9880d681SAndroid Build Coastguard Worker; CHECK: cije %r2, 0 170*9880d681SAndroid Build Coastguard Worker; CHECK: crjlh %r2, 171*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14 172*9880d681SAndroid Build Coastguard Workerentry: 173*9880d681SAndroid Build Coastguard Worker %cmp11 = icmp eq i32 %a, 0 174*9880d681SAndroid Build Coastguard Worker br i1 %cmp11, label %while.end, label %while.body 175*9880d681SAndroid Build Coastguard Worker 176*9880d681SAndroid Build Coastguard Workerwhile.body: 177*9880d681SAndroid Build Coastguard Worker %c = call i32 @foo() 178*9880d681SAndroid Build Coastguard Worker %cmp12 = icmp eq i32 %c, %b 179*9880d681SAndroid Build Coastguard Worker br i1 %cmp12, label %while.end, label %while.body 180*9880d681SAndroid Build Coastguard Worker 181*9880d681SAndroid Build Coastguard Workerwhile.end: 182*9880d681SAndroid Build Coastguard Worker ret void 183*9880d681SAndroid Build Coastguard Worker} 184*9880d681SAndroid Build Coastguard Worker 185*9880d681SAndroid Build Coastguard Worker; Check the comparison can be reversed if that allows C to be used. 186*9880d681SAndroid Build Coastguard Workerdefine double @f13(double %a, double %b, i32 %i2, i32 *%ptr) { 187*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f13: 188*9880d681SAndroid Build Coastguard Worker; CHECK: c %r2, 0(%r3) 189*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: bhr %r14 190*9880d681SAndroid Build Coastguard Worker; CHECK: ldr %f0, %f2 191*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14 192*9880d681SAndroid Build Coastguard Worker %i1 = load i32 , i32 *%ptr 193*9880d681SAndroid Build Coastguard Worker %cond = icmp slt i32 %i1, %i2 194*9880d681SAndroid Build Coastguard Worker %res = select i1 %cond, double %a, double %b 195*9880d681SAndroid Build Coastguard Worker ret double %res 196*9880d681SAndroid Build Coastguard Worker} 197