1 ; Test conditional sibling calls. 2 ; 3 ; RUN: llc < %s -mtriple=s390x-linux-gnu | FileCheck %s 4 5 6 @var = global i32 1; 7 @fun_a = global void()* null; 8 @fun_b = global void()* null; 9 @fun_c = global void(i32)* null; 10 11 ; Check a conditional sibling call. 12 define void @f1(i32 %val1, i32 %val2) { 13 ; CHECK-LABEL: f1: 14 ; CHECK: crbl %r2, %r3, 0(%r1) 15 ; CHECK: br %r14 16 %fun_a = load volatile void() *, void()** @fun_a; 17 %cond = icmp slt i32 %val1, %val2; 18 br i1 %cond, label %a, label %b; 19 20 a: 21 tail call void %fun_a() 22 ret void 23 24 b: 25 store i32 1, i32 *@var; 26 ret void 27 } 28 29 ; Check a conditional sibling call when there are two possibilities. 30 define void @f2(i32 %val1, i32 %val2) { 31 ; CHECK-LABEL: f2: 32 ; CHECK: crbl %r2, %r3, 0(%r1) 33 ; CHECK: br %r1 34 %fun_a = load volatile void() *, void()** @fun_a; 35 %fun_b = load volatile void() *, void()** @fun_b; 36 %cond = icmp slt i32 %val1, %val2; 37 br i1 %cond, label %a, label %b; 38 39 a: 40 tail call void %fun_a() 41 ret void 42 43 b: 44 tail call void %fun_b() 45 ret void 46 } 47 48 ; Check a conditional sibling call with an argument - not supported. 49 define void @f3(i32 %val1, i32 %val2) { 50 ; CHECK-LABEL: f3: 51 ; CHECK: crjhe %r2, %r3 52 ; CHECK: br %r1 53 ; CHECK: br %r14 54 %fun_c = load volatile void(i32) *, void(i32)** @fun_c; 55 %cond = icmp slt i32 %val1, %val2; 56 br i1 %cond, label %a, label %b; 57 58 a: 59 tail call void %fun_c(i32 1) 60 ret void 61 62 b: 63 store i32 1, i32 *@var; 64 ret void 65 } 66 67 ; Check a conditional sibling call - unsigned compare. 68 define void @f4(i32 %val1, i32 %val2) { 69 ; CHECK-LABEL: f4: 70 ; CHECK: clrbl %r2, %r3, 0(%r1) 71 ; CHECK: br %r14 72 %fun_a = load volatile void() *, void()** @fun_a; 73 %cond = icmp ult i32 %val1, %val2; 74 br i1 %cond, label %a, label %b; 75 76 a: 77 tail call void %fun_a() 78 ret void 79 80 b: 81 store i32 1, i32 *@var; 82 ret void 83 } 84 85 ; Check a conditional sibling call - 64-bit compare. 86 define void @f5(i64 %val1, i64 %val2) { 87 ; CHECK-LABEL: f5: 88 ; CHECK: cgrbl %r2, %r3, 0(%r1) 89 ; CHECK: br %r14 90 %fun_a = load volatile void() *, void()** @fun_a; 91 %cond = icmp slt i64 %val1, %val2; 92 br i1 %cond, label %a, label %b; 93 94 a: 95 tail call void %fun_a() 96 ret void 97 98 b: 99 store i32 1, i32 *@var; 100 ret void 101 } 102 103 ; Check a conditional sibling call - unsigned 64-bit compare. 104 define void @f6(i64 %val1, i64 %val2) { 105 ; CHECK-LABEL: f6: 106 ; CHECK: clgrbl %r2, %r3, 0(%r1) 107 ; CHECK: br %r14 108 %fun_a = load volatile void() *, void()** @fun_a; 109 %cond = icmp ult i64 %val1, %val2; 110 br i1 %cond, label %a, label %b; 111 112 a: 113 tail call void %fun_a() 114 ret void 115 116 b: 117 store i32 1, i32 *@var; 118 ret void 119 } 120 121 ; Check a conditional sibling call - less-equal compare. 122 define void @f7(i32 %val1, i32 %val2) { 123 ; CHECK-LABEL: f7: 124 ; CHECK: crble %r2, %r3, 0(%r1) 125 ; CHECK: br %r14 126 %fun_a = load volatile void() *, void()** @fun_a; 127 %cond = icmp sle i32 %val1, %val2; 128 br i1 %cond, label %a, label %b; 129 130 a: 131 tail call void %fun_a() 132 ret void 133 134 b: 135 store i32 1, i32 *@var; 136 ret void 137 } 138 139 ; Check a conditional sibling call - high compare. 140 define void @f8(i32 %val1, i32 %val2) { 141 ; CHECK-LABEL: f8: 142 ; CHECK: crbh %r2, %r3, 0(%r1) 143 ; CHECK: br %r14 144 %fun_a = load volatile void() *, void()** @fun_a; 145 %cond = icmp sgt i32 %val1, %val2; 146 br i1 %cond, label %a, label %b; 147 148 a: 149 tail call void %fun_a() 150 ret void 151 152 b: 153 store i32 1, i32 *@var; 154 ret void 155 } 156 157 ; Check a conditional sibling call - high-equal compare. 158 define void @f9(i32 %val1, i32 %val2) { 159 ; CHECK-LABEL: f9: 160 ; CHECK: crbhe %r2, %r3, 0(%r1) 161 ; CHECK: br %r14 162 %fun_a = load volatile void() *, void()** @fun_a; 163 %cond = icmp sge i32 %val1, %val2; 164 br i1 %cond, label %a, label %b; 165 166 a: 167 tail call void %fun_a() 168 ret void 169 170 b: 171 store i32 1, i32 *@var; 172 ret void 173 } 174 175 ; Check a conditional sibling call - equal compare. 176 define void @f10(i32 %val1, i32 %val2) { 177 ; CHECK-LABEL: f10: 178 ; CHECK: crbe %r2, %r3, 0(%r1) 179 ; CHECK: br %r14 180 %fun_a = load volatile void() *, void()** @fun_a; 181 %cond = icmp eq i32 %val1, %val2; 182 br i1 %cond, label %a, label %b; 183 184 a: 185 tail call void %fun_a() 186 ret void 187 188 b: 189 store i32 1, i32 *@var; 190 ret void 191 } 192 193 ; Check a conditional sibling call - unequal compare. 194 define void @f11(i32 %val1, i32 %val2) { 195 ; CHECK-LABEL: f11: 196 ; CHECK: crblh %r2, %r3, 0(%r1) 197 ; CHECK: br %r14 198 %fun_a = load volatile void() *, void()** @fun_a; 199 %cond = icmp ne i32 %val1, %val2; 200 br i1 %cond, label %a, label %b; 201 202 a: 203 tail call void %fun_a() 204 ret void 205 206 b: 207 store i32 1, i32 *@var; 208 ret void 209 } 210 211 ; Check a conditional sibling call - immediate slt. 212 define void @f12(i32 %val1) { 213 ; CHECK-LABEL: f12: 214 ; CHECK: cible %r2, 4, 0(%r1) 215 ; CHECK: br %r14 216 %fun_a = load volatile void() *, void()** @fun_a; 217 %cond = icmp slt i32 %val1, 5; 218 br i1 %cond, label %a, label %b; 219 220 a: 221 tail call void %fun_a() 222 ret void 223 224 b: 225 store i32 1, i32 *@var; 226 ret void 227 } 228 229 ; Check a conditional sibling call - immediate sle. 230 define void @f13(i32 %val1) { 231 ; CHECK-LABEL: f13: 232 ; CHECK: cible %r2, 5, 0(%r1) 233 ; CHECK: br %r14 234 %fun_a = load volatile void() *, void()** @fun_a; 235 %cond = icmp sle i32 %val1, 5; 236 br i1 %cond, label %a, label %b; 237 238 a: 239 tail call void %fun_a() 240 ret void 241 242 b: 243 store i32 1, i32 *@var; 244 ret void 245 } 246 247 ; Check a conditional sibling call - immediate sgt. 248 define void @f14(i32 %val1) { 249 ; CHECK-LABEL: f14: 250 ; CHECK: cibhe %r2, 6, 0(%r1) 251 ; CHECK: br %r14 252 %fun_a = load volatile void() *, void()** @fun_a; 253 %cond = icmp sgt i32 %val1, 5; 254 br i1 %cond, label %a, label %b; 255 256 a: 257 tail call void %fun_a() 258 ret void 259 260 b: 261 store i32 1, i32 *@var; 262 ret void 263 } 264 265 ; Check a conditional sibling call - immediate sge. 266 define void @f15(i32 %val1) { 267 ; CHECK-LABEL: f15: 268 ; CHECK: cibhe %r2, 5, 0(%r1) 269 ; CHECK: br %r14 270 %fun_a = load volatile void() *, void()** @fun_a; 271 %cond = icmp sge i32 %val1, 5; 272 br i1 %cond, label %a, label %b; 273 274 a: 275 tail call void %fun_a() 276 ret void 277 278 b: 279 store i32 1, i32 *@var; 280 ret void 281 } 282 283 ; Check a conditional sibling call - immediate eq. 284 define void @f16(i32 %val1) { 285 ; CHECK-LABEL: f16: 286 ; CHECK: cibe %r2, 5, 0(%r1) 287 ; CHECK: br %r14 288 %fun_a = load volatile void() *, void()** @fun_a; 289 %cond = icmp eq i32 %val1, 5; 290 br i1 %cond, label %a, label %b; 291 292 a: 293 tail call void %fun_a() 294 ret void 295 296 b: 297 store i32 1, i32 *@var; 298 ret void 299 } 300 301 ; Check a conditional sibling call - immediate ne. 302 define void @f17(i32 %val1) { 303 ; CHECK-LABEL: f17: 304 ; CHECK: ciblh %r2, 5, 0(%r1) 305 ; CHECK: br %r14 306 %fun_a = load volatile void() *, void()** @fun_a; 307 %cond = icmp ne i32 %val1, 5; 308 br i1 %cond, label %a, label %b; 309 310 a: 311 tail call void %fun_a() 312 ret void 313 314 b: 315 store i32 1, i32 *@var; 316 ret void 317 } 318 319 ; Check a conditional sibling call - immediate ult. 320 define void @f18(i32 %val1) { 321 ; CHECK-LABEL: f18: 322 ; CHECK: clible %r2, 4, 0(%r1) 323 ; CHECK: br %r14 324 %fun_a = load volatile void() *, void()** @fun_a; 325 %cond = icmp ult i32 %val1, 5; 326 br i1 %cond, label %a, label %b; 327 328 a: 329 tail call void %fun_a() 330 ret void 331 332 b: 333 store i32 1, i32 *@var; 334 ret void 335 } 336 337 ; Check a conditional sibling call - immediate 64-bit slt. 338 define void @f19(i64 %val1) { 339 ; CHECK-LABEL: f19: 340 ; CHECK: cgible %r2, 4, 0(%r1) 341 ; CHECK: br %r14 342 %fun_a = load volatile void() *, void()** @fun_a; 343 %cond = icmp slt i64 %val1, 5; 344 br i1 %cond, label %a, label %b; 345 346 a: 347 tail call void %fun_a() 348 ret void 349 350 b: 351 store i32 1, i32 *@var; 352 ret void 353 } 354 355 ; Check a conditional sibling call - immediate 64-bit ult. 356 define void @f20(i64 %val1) { 357 ; CHECK-LABEL: f20: 358 ; CHECK: clgible %r2, 4, 0(%r1) 359 ; CHECK: br %r14 360 %fun_a = load volatile void() *, void()** @fun_a; 361 %cond = icmp ult i64 %val1, 5; 362 br i1 %cond, label %a, label %b; 363 364 a: 365 tail call void %fun_a() 366 ret void 367 368 b: 369 store i32 1, i32 *@var; 370 ret void 371 } 372 373 ; Check a conditional sibling call to an argument - will fail due to 374 ; intervening lgr. 375 define void @f21(i32 %val1, i32 %val2, void()* %fun) { 376 ; CHECK-LABEL: f21: 377 ; CHECK: crjhe %r2, %r3 378 ; CHECK: lgr %r1, %r4 379 ; CHECK: br %r1 380 ; CHECK: br %r14 381 %cond = icmp slt i32 %val1, %val2; 382 br i1 %cond, label %a, label %b; 383 384 a: 385 tail call void %fun() 386 ret void 387 388 b: 389 store i32 1, i32 *@var; 390 ret void 391 } 392 393 ; Check a conditional sibling call - float olt compare. 394 define void @f22(float %val1, float %val2) { 395 ; CHECK-LABEL: f22: 396 ; CHECK: cebr %f0, %f2 397 ; CHECK: blr %r1 398 ; CHECK: br %r14 399 %fun_a = load volatile void() *, void()** @fun_a; 400 %cond = fcmp olt float %val1, %val2; 401 br i1 %cond, label %a, label %b; 402 403 a: 404 tail call void %fun_a() 405 ret void 406 407 b: 408 store i32 1, i32 *@var; 409 ret void 410 } 411 412 ; Check a conditional sibling call - float ult compare. 413 define void @f23(float %val1, float %val2) { 414 ; CHECK-LABEL: f23: 415 ; CHECK: cebr %f0, %f2 416 ; CHECK: bnher %r1 417 ; CHECK: br %r14 418 %fun_a = load volatile void() *, void()** @fun_a; 419 %cond = fcmp ult float %val1, %val2; 420 br i1 %cond, label %a, label %b; 421 422 a: 423 tail call void %fun_a() 424 ret void 425 426 b: 427 store i32 1, i32 *@var; 428 ret void 429 } 430 431 ; Check a conditional sibling call - float ord compare. 432 define void @f24(float %val1, float %val2) { 433 ; CHECK-LABEL: f24: 434 ; CHECK: cebr %f0, %f2 435 ; CHECK: bnor %r1 436 ; CHECK: br %r14 437 %fun_a = load volatile void() *, void()** @fun_a; 438 %cond = fcmp ord float %val1, %val2; 439 br i1 %cond, label %a, label %b; 440 441 a: 442 tail call void %fun_a() 443 ret void 444 445 b: 446 store i32 1, i32 *@var; 447 ret void 448 } 449 450 ; Check a conditional sibling call - float uno compare. 451 define void @f25(float %val1, float %val2) { 452 ; CHECK-LABEL: f25: 453 ; CHECK: cebr %f0, %f2 454 ; CHECK: bor %r1 455 ; CHECK: br %r14 456 %fun_a = load volatile void() *, void()** @fun_a; 457 %cond = fcmp uno float %val1, %val2; 458 br i1 %cond, label %a, label %b; 459 460 a: 461 tail call void %fun_a() 462 ret void 463 464 b: 465 store i32 1, i32 *@var; 466 ret void 467 } 468