1; Test 64-bit comparison in which the second operand is a sign-extended i32. 2; 3; RUN: llc < %s -mtriple=s390x-linux-gnu | FileCheck %s 4 5declare i64 @foo() 6 7; Check signed register comparison. 8define double @f1(double %a, double %b, i64 %i1, i32 %unext) { 9; CHECK-LABEL: f1: 10; CHECK: cgfr %r2, %r3 11; CHECK-NEXT: jl 12; CHECK: ldr %f0, %f2 13; CHECK: br %r14 14 %i2 = sext i32 %unext to i64 15 %cond = icmp slt i64 %i1, %i2 16 %res = select i1 %cond, double %a, double %b 17 ret double %res 18} 19 20; Check unsigned register comparison, which can't use CGFR. 21define double @f2(double %a, double %b, i64 %i1, i32 %unext) { 22; CHECK-LABEL: f2: 23; CHECK-NOT: cgfr 24; CHECK: br %r14 25 %i2 = sext i32 %unext to i64 26 %cond = icmp ult i64 %i1, %i2 27 %res = select i1 %cond, double %a, double %b 28 ret double %res 29} 30 31; Check register equality. 32define double @f3(double %a, double %b, i64 %i1, i32 %unext) { 33; CHECK-LABEL: f3: 34; CHECK: cgfr %r2, %r3 35; CHECK-NEXT: je 36; CHECK: ldr %f0, %f2 37; CHECK: br %r14 38 %i2 = sext i32 %unext to i64 39 %cond = icmp eq i64 %i1, %i2 40 %res = select i1 %cond, double %a, double %b 41 ret double %res 42} 43 44; Check register inequality. 45define double @f4(double %a, double %b, i64 %i1, i32 %unext) { 46; CHECK-LABEL: f4: 47; CHECK: cgfr %r2, %r3 48; CHECK-NEXT: jlh 49; CHECK: ldr %f0, %f2 50; CHECK: br %r14 51 %i2 = sext i32 %unext to i64 52 %cond = icmp ne i64 %i1, %i2 53 %res = select i1 %cond, double %a, double %b 54 ret double %res 55} 56 57; Check signed comparison with memory. 58define double @f5(double %a, double %b, i64 %i1, i32 *%ptr) { 59; CHECK-LABEL: f5: 60; CHECK: cgf %r2, 0(%r3) 61; CHECK-NEXT: jl 62; CHECK: ldr %f0, %f2 63; CHECK: br %r14 64 %unext = load i32 , i32 *%ptr 65 %i2 = sext i32 %unext to i64 66 %cond = icmp slt i64 %i1, %i2 67 %res = select i1 %cond, double %a, double %b 68 ret double %res 69} 70 71; Check unsigned comparison with memory. 72define double @f6(double %a, double %b, i64 %i1, i32 *%ptr) { 73; CHECK-LABEL: f6: 74; CHECK-NOT: cgf 75; CHECK: br %r14 76 %unext = load i32 , i32 *%ptr 77 %i2 = sext i32 %unext to i64 78 %cond = icmp ult i64 %i1, %i2 79 %res = select i1 %cond, double %a, double %b 80 ret double %res 81} 82 83; Check memory equality. 84define double @f7(double %a, double %b, i64 %i1, i32 *%ptr) { 85; CHECK-LABEL: f7: 86; CHECK: cgf %r2, 0(%r3) 87; CHECK-NEXT: je 88; CHECK: ldr %f0, %f2 89; CHECK: br %r14 90 %unext = load i32 , i32 *%ptr 91 %i2 = sext i32 %unext to i64 92 %cond = icmp eq i64 %i1, %i2 93 %res = select i1 %cond, double %a, double %b 94 ret double %res 95} 96 97; Check memory inequality. 98define double @f8(double %a, double %b, i64 %i1, i32 *%ptr) { 99; CHECK-LABEL: f8: 100; CHECK: cgf %r2, 0(%r3) 101; CHECK-NEXT: jlh 102; CHECK: ldr %f0, %f2 103; CHECK: br %r14 104 %unext = load i32 , i32 *%ptr 105 %i2 = sext i32 %unext to i64 106 %cond = icmp ne i64 %i1, %i2 107 %res = select i1 %cond, double %a, double %b 108 ret double %res 109} 110 111; Check the high end of the aligned CGF range. 112define double @f9(double %a, double %b, i64 %i1, i32 *%base) { 113; CHECK-LABEL: f9: 114; CHECK: cgf %r2, 524284(%r3) 115; CHECK-NEXT: jl 116; CHECK: ldr %f0, %f2 117; CHECK: br %r14 118 %ptr = getelementptr i32, i32 *%base, i64 131071 119 %unext = load i32 , i32 *%ptr 120 %i2 = sext i32 %unext to i64 121 %cond = icmp slt i64 %i1, %i2 122 %res = select i1 %cond, double %a, double %b 123 ret double %res 124} 125 126; Check the next word up, which needs separate address logic. 127; Other sequences besides this one would be OK. 128define double @f10(double %a, double %b, i64 %i1, i32 *%base) { 129; CHECK-LABEL: f10: 130; CHECK: agfi %r3, 524288 131; CHECK: cgf %r2, 0(%r3) 132; CHECK-NEXT: jl 133; CHECK: ldr %f0, %f2 134; CHECK: br %r14 135 %ptr = getelementptr i32, i32 *%base, i64 131072 136 %unext = load i32 , i32 *%ptr 137 %i2 = sext i32 %unext to i64 138 %cond = icmp slt i64 %i1, %i2 139 %res = select i1 %cond, double %a, double %b 140 ret double %res 141} 142 143; Check the high end of the negative aligned CGF range. 144define double @f11(double %a, double %b, i64 %i1, i32 *%base) { 145; CHECK-LABEL: f11: 146; CHECK: cgf %r2, -4(%r3) 147; CHECK-NEXT: jl 148; CHECK: ldr %f0, %f2 149; CHECK: br %r14 150 %ptr = getelementptr i32, i32 *%base, i64 -1 151 %unext = load i32 , i32 *%ptr 152 %i2 = sext i32 %unext to i64 153 %cond = icmp slt i64 %i1, %i2 154 %res = select i1 %cond, double %a, double %b 155 ret double %res 156} 157 158; Check the low end of the CGF range. 159define double @f12(double %a, double %b, i64 %i1, i32 *%base) { 160; CHECK-LABEL: f12: 161; CHECK: cgf %r2, -524288(%r3) 162; CHECK-NEXT: jl 163; CHECK: ldr %f0, %f2 164; CHECK: br %r14 165 %ptr = getelementptr i32, i32 *%base, i64 -131072 166 %unext = load i32 , i32 *%ptr 167 %i2 = sext i32 %unext to i64 168 %cond = icmp slt i64 %i1, %i2 169 %res = select i1 %cond, double %a, double %b 170 ret double %res 171} 172 173; Check the next word down, which needs separate address logic. 174; Other sequences besides this one would be OK. 175define double @f13(double %a, double %b, i64 %i1, i32 *%base) { 176; CHECK-LABEL: f13: 177; CHECK: agfi %r3, -524292 178; CHECK: cgf %r2, 0(%r3) 179; CHECK-NEXT: jl 180; CHECK: ldr %f0, %f2 181; CHECK: br %r14 182 %ptr = getelementptr i32, i32 *%base, i64 -131073 183 %unext = load i32 , i32 *%ptr 184 %i2 = sext i32 %unext to i64 185 %cond = icmp slt i64 %i1, %i2 186 %res = select i1 %cond, double %a, double %b 187 ret double %res 188} 189 190; Check that CGF allows an index. 191define double @f14(double %a, double %b, i64 %i1, i64 %base, i64 %index) { 192; CHECK-LABEL: f14: 193; CHECK: cgf %r2, 524284({{%r4,%r3|%r3,%r4}}) 194; CHECK-NEXT: jl 195; CHECK: ldr %f0, %f2 196; CHECK: br %r14 197 %add1 = add i64 %base, %index 198 %add2 = add i64 %add1, 524284 199 %ptr = inttoptr i64 %add2 to i32 * 200 %unext = load i32 , i32 *%ptr 201 %i2 = sext i32 %unext to i64 202 %cond = icmp slt i64 %i1, %i2 203 %res = select i1 %cond, double %a, double %b 204 ret double %res 205} 206 207; Check that comparisons of spilled values can use CGF rather than CGFR. 208define i64 @f15(i32 *%ptr0) { 209; CHECK-LABEL: f15: 210; CHECK: brasl %r14, foo@PLT 211; CHECK: cgf {{%r[0-9]+}}, 16{{[04]}}(%r15) 212; CHECK: br %r14 213 %ptr1 = getelementptr i32, i32 *%ptr0, i64 2 214 %ptr2 = getelementptr i32, i32 *%ptr0, i64 4 215 %ptr3 = getelementptr i32, i32 *%ptr0, i64 6 216 %ptr4 = getelementptr i32, i32 *%ptr0, i64 8 217 %ptr5 = getelementptr i32, i32 *%ptr0, i64 10 218 %ptr6 = getelementptr i32, i32 *%ptr0, i64 12 219 %ptr7 = getelementptr i32, i32 *%ptr0, i64 14 220 %ptr8 = getelementptr i32, i32 *%ptr0, i64 16 221 %ptr9 = getelementptr i32, i32 *%ptr0, i64 18 222 223 %val0 = load i32 , i32 *%ptr0 224 %val1 = load i32 , i32 *%ptr1 225 %val2 = load i32 , i32 *%ptr2 226 %val3 = load i32 , i32 *%ptr3 227 %val4 = load i32 , i32 *%ptr4 228 %val5 = load i32 , i32 *%ptr5 229 %val6 = load i32 , i32 *%ptr6 230 %val7 = load i32 , i32 *%ptr7 231 %val8 = load i32 , i32 *%ptr8 232 %val9 = load i32 , i32 *%ptr9 233 234 %frob0 = add i32 %val0, 100 235 %frob1 = add i32 %val1, 100 236 %frob2 = add i32 %val2, 100 237 %frob3 = add i32 %val3, 100 238 %frob4 = add i32 %val4, 100 239 %frob5 = add i32 %val5, 100 240 %frob6 = add i32 %val6, 100 241 %frob7 = add i32 %val7, 100 242 %frob8 = add i32 %val8, 100 243 %frob9 = add i32 %val9, 100 244 245 store i32 %frob0, i32 *%ptr0 246 store i32 %frob1, i32 *%ptr1 247 store i32 %frob2, i32 *%ptr2 248 store i32 %frob3, i32 *%ptr3 249 store i32 %frob4, i32 *%ptr4 250 store i32 %frob5, i32 *%ptr5 251 store i32 %frob6, i32 *%ptr6 252 store i32 %frob7, i32 *%ptr7 253 store i32 %frob8, i32 *%ptr8 254 store i32 %frob9, i32 *%ptr9 255 256 %ret = call i64 @foo() 257 258 %ext0 = sext i32 %frob0 to i64 259 %ext1 = sext i32 %frob1 to i64 260 %ext2 = sext i32 %frob2 to i64 261 %ext3 = sext i32 %frob3 to i64 262 %ext4 = sext i32 %frob4 to i64 263 %ext5 = sext i32 %frob5 to i64 264 %ext6 = sext i32 %frob6 to i64 265 %ext7 = sext i32 %frob7 to i64 266 %ext8 = sext i32 %frob8 to i64 267 %ext9 = sext i32 %frob9 to i64 268 269 %cmp0 = icmp slt i64 %ret, %ext0 270 %cmp1 = icmp slt i64 %ret, %ext1 271 %cmp2 = icmp slt i64 %ret, %ext2 272 %cmp3 = icmp slt i64 %ret, %ext3 273 %cmp4 = icmp slt i64 %ret, %ext4 274 %cmp5 = icmp slt i64 %ret, %ext5 275 %cmp6 = icmp slt i64 %ret, %ext6 276 %cmp7 = icmp slt i64 %ret, %ext7 277 %cmp8 = icmp slt i64 %ret, %ext8 278 %cmp9 = icmp slt i64 %ret, %ext9 279 280 %sel0 = select i1 %cmp0, i64 %ret, i64 0 281 %sel1 = select i1 %cmp1, i64 %sel0, i64 1 282 %sel2 = select i1 %cmp2, i64 %sel1, i64 2 283 %sel3 = select i1 %cmp3, i64 %sel2, i64 3 284 %sel4 = select i1 %cmp4, i64 %sel3, i64 4 285 %sel5 = select i1 %cmp5, i64 %sel4, i64 5 286 %sel6 = select i1 %cmp6, i64 %sel5, i64 6 287 %sel7 = select i1 %cmp7, i64 %sel6, i64 7 288 %sel8 = select i1 %cmp8, i64 %sel7, i64 8 289 %sel9 = select i1 %cmp9, i64 %sel8, i64 9 290 291 ret i64 %sel9 292} 293 294; Check the comparison can be reversed if that allows CGFR to be used. 295define double @f16(double %a, double %b, i64 %i1, i32 %unext) { 296; CHECK-LABEL: f16: 297; CHECK: cgfr %r2, %r3 298; CHECK-NEXT: jh 299; CHECK: ldr %f0, %f2 300; CHECK: br %r14 301 %i2 = sext i32 %unext to i64 302 %cond = icmp slt i64 %i2, %i1 303 %res = select i1 %cond, double %a, double %b 304 ret double %res 305} 306 307; Likewise CGF. 308define double @f17(double %a, double %b, i64 %i2, i32 *%ptr) { 309; CHECK-LABEL: f17: 310; CHECK: cgf %r2, 0(%r3) 311; CHECK-NEXT: jh {{\.L.*}} 312; CHECK: ldr %f0, %f2 313; CHECK: br %r14 314 %unext = load i32 , i32 *%ptr 315 %i1 = sext i32 %unext to i64 316 %cond = icmp slt i64 %i1, %i2 317 %res = select i1 %cond, double %a, double %b 318 ret double %res 319} 320