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