1; Test 64-bit comparison in which the second operand is a zero-extended i32. 2; 3; RUN: llc < %s -mtriple=s390x-linux-gnu | FileCheck %s 4 5; Check unsigned register comparison. 6define double @f1(double %a, double %b, i64 %i1, i32 %unext) { 7; CHECK: f1: 8; CHECK: clgfr %r2, %r3 9; CHECK-NEXT: jl 10; CHECK: ldr %f0, %f2 11; CHECK: br %r14 12 %i2 = zext i32 %unext to i64 13 %cond = icmp ult i64 %i1, %i2 14 %res = select i1 %cond, double %a, double %b 15 ret double %res 16} 17 18; ...and again with a different representation. 19define double @f2(double %a, double %b, i64 %i1, i64 %unext) { 20; CHECK: f2: 21; CHECK: clgfr %r2, %r3 22; CHECK-NEXT: jl 23; CHECK: ldr %f0, %f2 24; CHECK: br %r14 25 %i2 = and i64 %unext, 4294967295 26 %cond = icmp ult i64 %i1, %i2 27 %res = select i1 %cond, double %a, double %b 28 ret double %res 29} 30 31; Check signed register comparison, which can't use CLGFR. 32define double @f3(double %a, double %b, i64 %i1, i32 %unext) { 33; CHECK: f3: 34; CHECK-NOT: clgfr 35; CHECK: br %r14 36 %i2 = zext i32 %unext to i64 37 %cond = icmp slt i64 %i1, %i2 38 %res = select i1 %cond, double %a, double %b 39 ret double %res 40} 41 42; ...and again with a different representation 43define double @f4(double %a, double %b, i64 %i1, i64 %unext) { 44; CHECK: f4: 45; CHECK-NOT: clgfr 46; CHECK: br %r14 47 %i2 = and i64 %unext, 4294967295 48 %cond = icmp slt i64 %i1, %i2 49 %res = select i1 %cond, double %a, double %b 50 ret double %res 51} 52 53; Check register equality. 54define double @f5(double %a, double %b, i64 %i1, i32 %unext) { 55; CHECK: f5: 56; CHECK: clgfr %r2, %r3 57; CHECK-NEXT: je 58; CHECK: ldr %f0, %f2 59; CHECK: br %r14 60 %i2 = zext i32 %unext to i64 61 %cond = icmp eq i64 %i1, %i2 62 %res = select i1 %cond, double %a, double %b 63 ret double %res 64} 65 66; ...and again with a different representation 67define double @f6(double %a, double %b, i64 %i1, i64 %unext) { 68; CHECK: f6: 69; CHECK: clgfr %r2, %r3 70; CHECK-NEXT: je 71; CHECK: ldr %f0, %f2 72; CHECK: br %r14 73 %i2 = and i64 %unext, 4294967295 74 %cond = icmp eq i64 %i1, %i2 75 %res = select i1 %cond, double %a, double %b 76 ret double %res 77} 78 79; Check register inequality. 80define double @f7(double %a, double %b, i64 %i1, i32 %unext) { 81; CHECK: f7: 82; CHECK: clgfr %r2, %r3 83; CHECK-NEXT: jlh 84; CHECK: ldr %f0, %f2 85; CHECK: br %r14 86 %i2 = zext i32 %unext to i64 87 %cond = icmp ne i64 %i1, %i2 88 %res = select i1 %cond, double %a, double %b 89 ret double %res 90} 91 92; ...and again with a different representation 93define double @f8(double %a, double %b, i64 %i1, i64 %unext) { 94; CHECK: f8: 95; CHECK: clgfr %r2, %r3 96; CHECK-NEXT: jlh 97; CHECK: ldr %f0, %f2 98; CHECK: br %r14 99 %i2 = and i64 %unext, 4294967295 100 %cond = icmp ne i64 %i1, %i2 101 %res = select i1 %cond, double %a, double %b 102 ret double %res 103} 104 105; Check unsigned comparisonn with memory. 106define double @f9(double %a, double %b, i64 %i1, i32 *%ptr) { 107; CHECK: f9: 108; CHECK: clgf %r2, 0(%r3) 109; CHECK-NEXT: jl 110; CHECK: ldr %f0, %f2 111; CHECK: br %r14 112 %unext = load i32 *%ptr 113 %i2 = zext i32 %unext to i64 114 %cond = icmp ult i64 %i1, %i2 115 %res = select i1 %cond, double %a, double %b 116 ret double %res 117} 118 119; Check signed comparison with memory. 120define double @f10(double %a, double %b, i64 %i1, i32 *%ptr) { 121; CHECK: f10: 122; CHECK-NOT: clgf 123; CHECK: br %r14 124 %unext = load i32 *%ptr 125 %i2 = zext i32 %unext to i64 126 %cond = icmp slt i64 %i1, %i2 127 %res = select i1 %cond, double %a, double %b 128 ret double %res 129} 130 131; Check memory equality. 132define double @f11(double %a, double %b, i64 %i1, i32 *%ptr) { 133; CHECK: f11: 134; CHECK: clgf %r2, 0(%r3) 135; CHECK-NEXT: je 136; CHECK: ldr %f0, %f2 137; CHECK: br %r14 138 %unext = load i32 *%ptr 139 %i2 = zext i32 %unext to i64 140 %cond = icmp eq i64 %i1, %i2 141 %res = select i1 %cond, double %a, double %b 142 ret double %res 143} 144 145; Check memory inequality. 146define double @f12(double %a, double %b, i64 %i1, i32 *%ptr) { 147; CHECK: f12: 148; CHECK: clgf %r2, 0(%r3) 149; CHECK-NEXT: jlh 150; CHECK: ldr %f0, %f2 151; CHECK: br %r14 152 %unext = load i32 *%ptr 153 %i2 = zext i32 %unext to i64 154 %cond = icmp ne i64 %i1, %i2 155 %res = select i1 %cond, double %a, double %b 156 ret double %res 157} 158 159; Check the high end of the aligned CLGF range. 160define double @f13(double %a, double %b, i64 %i1, i32 *%base) { 161; CHECK: f13: 162; CHECK: clgf %r2, 524284(%r3) 163; CHECK-NEXT: jl 164; CHECK: ldr %f0, %f2 165; CHECK: br %r14 166 %ptr = getelementptr i32 *%base, i64 131071 167 %unext = load i32 *%ptr 168 %i2 = zext i32 %unext to i64 169 %cond = icmp ult i64 %i1, %i2 170 %res = select i1 %cond, double %a, double %b 171 ret double %res 172} 173 174; Check the next word up, which needs separate address logic. 175; Other sequences besides this one would be OK. 176define double @f14(double %a, double %b, i64 %i1, i32 *%base) { 177; CHECK: f14: 178; CHECK: agfi %r3, 524288 179; CHECK: clgf %r2, 0(%r3) 180; CHECK-NEXT: jl 181; CHECK: ldr %f0, %f2 182; CHECK: br %r14 183 %ptr = getelementptr i32 *%base, i64 131072 184 %unext = load i32 *%ptr 185 %i2 = zext i32 %unext to i64 186 %cond = icmp ult i64 %i1, %i2 187 %res = select i1 %cond, double %a, double %b 188 ret double %res 189} 190 191; Check the high end of the negative aligned CLGF range. 192define double @f15(double %a, double %b, i64 %i1, i32 *%base) { 193; CHECK: f15: 194; CHECK: clgf %r2, -4(%r3) 195; CHECK-NEXT: jl 196; CHECK: ldr %f0, %f2 197; CHECK: br %r14 198 %ptr = getelementptr i32 *%base, i64 -1 199 %unext = load i32 *%ptr 200 %i2 = zext i32 %unext to i64 201 %cond = icmp ult i64 %i1, %i2 202 %res = select i1 %cond, double %a, double %b 203 ret double %res 204} 205 206; Check the low end of the CLGF range. 207define double @f16(double %a, double %b, i64 %i1, i32 *%base) { 208; CHECK: f16: 209; CHECK: clgf %r2, -524288(%r3) 210; CHECK-NEXT: jl 211; CHECK: ldr %f0, %f2 212; CHECK: br %r14 213 %ptr = getelementptr i32 *%base, i64 -131072 214 %unext = load i32 *%ptr 215 %i2 = zext i32 %unext to i64 216 %cond = icmp ult i64 %i1, %i2 217 %res = select i1 %cond, double %a, double %b 218 ret double %res 219} 220 221; Check the next word down, which needs separate address logic. 222; Other sequences besides this one would be OK. 223define double @f17(double %a, double %b, i64 %i1, i32 *%base) { 224; CHECK: f17: 225; CHECK: agfi %r3, -524292 226; CHECK: clgf %r2, 0(%r3) 227; CHECK-NEXT: jl 228; CHECK: ldr %f0, %f2 229; CHECK: br %r14 230 %ptr = getelementptr i32 *%base, i64 -131073 231 %unext = load i32 *%ptr 232 %i2 = zext i32 %unext to i64 233 %cond = icmp ult i64 %i1, %i2 234 %res = select i1 %cond, double %a, double %b 235 ret double %res 236} 237 238; Check that CLGF allows an index. 239define double @f18(double %a, double %b, i64 %i1, i64 %base, i64 %index) { 240; CHECK: f18: 241; CHECK: clgf %r2, 524284({{%r4,%r3|%r3,%r4}}) 242; CHECK-NEXT: jl 243; CHECK: ldr %f0, %f2 244; CHECK: br %r14 245 %add1 = add i64 %base, %index 246 %add2 = add i64 %add1, 524284 247 %ptr = inttoptr i64 %add2 to i32 * 248 %unext = load i32 *%ptr 249 %i2 = zext i32 %unext to i64 250 %cond = icmp ult i64 %i1, %i2 251 %res = select i1 %cond, double %a, double %b 252 ret double %res 253} 254