1# RUN: llc -O0 -run-pass=regbankselect %s -o - -verify-machineinstrs | FileCheck %s --check-prefix=CHECK --check-prefix=FAST 2# RUN: llc -O0 -run-pass=regbankselect %s -regbankselect-greedy -o - -verify-machineinstrs | FileCheck %s --check-prefix=CHECK --check-prefix=GREEDY 3 4--- | 5 ; ModuleID = 'generic-virtual-registers-type-error.mir' 6 target datalayout = "e-m:o-i64:64-i128:128-n32:64-S128" 7 target triple = "aarch64--" 8 define void @defaultMapping() { 9 entry: 10 ret void 11 } 12 define void @defaultMappingVector() { 13 entry: 14 ret void 15 } 16 define void @defaultMapping1Repair() { 17 entry: 18 ret void 19 } 20 define void @defaultMapping2Repairs() { 21 entry: 22 ret void 23 } 24 define void @defaultMappingDefRepair() { 25 entry: 26 ret void 27 } 28 define void @phiPropagation(i32* %src, i32* %dst, i1 %cond) { 29 entry: 30 %srcVal = load i32, i32* %src 31 br i1 %cond, label %end, label %then 32 then: 33 %res = add i32 %srcVal, 36 34 br label %end 35 end: 36 %toStore = phi i32 [ %srcVal, %entry ], [ %res, %then ] 37 store i32 %toStore, i32* %dst 38 ret void 39 } 40 define void @defaultMappingUseRepairPhysReg() { 41 entry: 42 ret void 43 } 44 define void @defaultMappingDefRepairPhysReg() { 45 entry: 46 ret void 47 } 48 define void @greedyMappingOr() { 49 entry: 50 ret void 51 } 52 define void @greedyMappingOrWithConstraints() { 53 entry: 54 ret void 55 } 56 57 define void @ignoreTargetSpecificInst() { ret void } 58 59 define void @regBankSelected_property() { ret void } 60 61 define void @bitcast_s32_gpr() { ret void } 62 define void @bitcast_s32_fpr() { ret void } 63 define void @bitcast_s32_gpr_fpr() { ret void } 64 define void @bitcast_s32_fpr_gpr() { ret void } 65 define void @bitcast_s64_gpr() { ret void } 66 define void @bitcast_s64_fpr() { ret void } 67 define void @bitcast_s64_gpr_fpr() { ret void } 68 define void @bitcast_s64_fpr_gpr() { ret void } 69 define void @bitcast_s128() { ret void } 70 define void @copy_s128() { ret void } 71 define void @copy_s128_from_load() { ret void } 72 define void @copy_fp16() { ret void } 73 74 define i64 @greedyWithChainOfComputation(i64 %arg1, <2 x i32>* %addr) { 75 %varg1 = bitcast i64 %arg1 to <2 x i32> 76 %varg2 = load <2 x i32>, <2 x i32>* %addr 77 %vres = or <2 x i32> %varg1, %varg2 78 %res = bitcast <2 x i32> %vres to i64 79 ret i64 %res 80 } 81 82 define i64 @floatingPointLoad(i64 %arg1, double* %addr) { 83 %varg1 = bitcast i64 %arg1 to double 84 %varg2 = load double, double* %addr 85 %vres = fadd double %varg1, %varg2 86 %res = bitcast double %vres to i64 87 ret i64 %res 88 } 89 90 define void @floatingPointStore(i64 %arg1, double* %addr) { 91 %varg1 = bitcast i64 %arg1 to double 92 %vres = fadd double %varg1, %varg1 93 store double %vres, double* %addr 94 ret void 95 } 96 97 define void @fp16Ext32() { ret void } 98 define void @fp16Ext64() { ret void } 99 define void @fp32Ext64() { ret void } 100 101 define half @passFp16(half %p) { 102 entry: 103 ret half %p 104 } 105 106 define half @passFp16ViaAllocas(half %p) { 107 entry: 108 %p.addr = alloca half, align 2 109 store half %p, half* %p.addr, align 2 110 %0 = load half, half* %p.addr, align 2 111 ret half %0 112 } 113... 114 115--- 116# Check that we assign a relevant register bank for %0. 117# Based on the type i32, this should be gpr. 118name: defaultMapping 119legalized: true 120registers: 121 - { id: 0, class: _ } 122 - { id: 1, class: _ } 123body: | 124 bb.0.entry: 125 liveins: $x0 126 ; CHECK-LABEL: name: defaultMapping 127 ; CHECK: %1:gpr(s32) = G_ADD %0 128 %0(s32) = COPY $w0 129 %1(s32) = G_ADD %0, %0 130... 131 132--- 133# Check that we assign a relevant register bank for %0. 134# Based on the type <2 x i32>, this should be fpr. 135# FPR is used for both floating point and vector registers. 136name: defaultMappingVector 137legalized: true 138registers: 139 - { id: 0, class: _ } 140 - { id: 1, class: _ } 141body: | 142 bb.0.entry: 143 liveins: $d0 144 ; CHECK-LABEL: name: defaultMappingVector 145 ; CHECK: %0:fpr(<2 x s32>) = COPY $d0 146 ; CHECK: %1:fpr(<2 x s32>) = G_ADD %0 147 %0(<2 x s32>) = COPY $d0 148 %1(<2 x s32>) = G_ADD %0, %0 149... 150 151--- 152# Check that we repair the assignment for %0. 153# Indeed based on the source of the copy it should live 154# in FPR, but at the use, it should be GPR. 155name: defaultMapping1Repair 156legalized: true 157registers: 158 - { id: 0, class: _ } 159 - { id: 1, class: _ } 160 - { id: 2, class: _ } 161body: | 162 bb.0.entry: 163 liveins: $s0, $x0 164 ; CHECK-LABEL: name: defaultMapping1Repair 165 ; CHECK: %0:fpr(s32) = COPY $s0 166 ; CHECK-NEXT: %1:gpr(s32) = COPY $w0 167 ; CHECK-NEXT: %3:gpr(s32) = COPY %0 168 ; CHECK-NEXT: %2:gpr(s32) = G_ADD %3, %1 169 %0(s32) = COPY $s0 170 %1(s32) = COPY $w0 171 %2(s32) = G_ADD %0, %1 172... 173 174# Check that we repair the assignment for %0 differently for both uses. 175name: defaultMapping2Repairs 176legalized: true 177registers: 178 - { id: 0, class: _ } 179 - { id: 1, class: _ } 180body: | 181 bb.0.entry: 182 liveins: $s0, $x0 183 ; CHECK-LABEL: name: defaultMapping2Repairs 184 ; CHECK: %0:fpr(s32) = COPY $s0 185 ; CHECK-NEXT: %2:gpr(s32) = COPY %0 186 ; CHECK-NEXT: %3:gpr(s32) = COPY %0 187 ; CHECK-NEXT: %1:gpr(s32) = G_ADD %2, %3 188 %0(s32) = COPY $s0 189 %1(s32) = G_ADD %0, %0 190... 191 192--- 193# Check that we repair the definition of %1. 194# %1 is forced to be into FPR, but its definition actually 195# requires that it lives in GPR. Make sure regbankselect 196# fixes that. 197name: defaultMappingDefRepair 198legalized: true 199registers: 200 - { id: 0, class: _ } 201 - { id: 1, class: fpr } 202body: | 203 bb.0.entry: 204 liveins: $w0 205 ; CHECK-LABEL: name: defaultMappingDefRepair 206 ; CHECK: %0:gpr(s32) = COPY $w0 207 ; CHECK-NEXT: %2:gpr(s32) = G_ADD %0, %0 208 ; CHECK-NEXT: %1:fpr(s32) = COPY %2 209 %0(s32) = COPY $w0 210 %1(s32) = G_ADD %0, %0 211... 212 213--- 214# Check that we are able to propagate register banks from phis. 215name: phiPropagation 216legalized: true 217tracksRegLiveness: true 218# CHECK: registers: 219# CHECK-NEXT: - { id: 0, class: gpr32, preferred-register: '' } 220# CHECK-NEXT: - { id: 1, class: gpr64sp, preferred-register: '' } 221# CHECK-NEXT: - { id: 2, class: gpr32, preferred-register: '' } 222# CHECK-NEXT: - { id: 3, class: gpr, preferred-register: '' } 223# CHECK-NEXT: - { id: 4, class: gpr, preferred-register: '' } 224registers: 225 - { id: 0, class: gpr32 } 226 - { id: 1, class: gpr64sp } 227 - { id: 2, class: gpr32 } 228 - { id: 3, class: _ } 229 - { id: 4, class: _ } 230 - { id: 5, class: _ } 231body: | 232 bb.0.entry: 233 successors: %bb.2.end, %bb.1.then 234 liveins: $x0, $x1, $w2 235 236 %0 = LDRWui killed $x0, 0 :: (load 4 from %ir.src) 237 %5(s32) = COPY %0 238 %1(p0) = COPY $x1 239 %2 = COPY $w2 240 TBNZW killed %2, 0, %bb.2.end 241 242 bb.1.then: 243 successors: %bb.2.end 244 %3(s32) = G_ADD %5, %5 245 246 bb.2.end: 247 %4(s32) = PHI %0, %bb.0.entry, %3, %bb.1.then 248 G_STORE killed %4, killed %1 :: (store 4 into %ir.dst) 249 RET_ReallyLR 250... 251 252--- 253# Make sure we can repair physical register uses as well. 254name: defaultMappingUseRepairPhysReg 255legalized: true 256registers: 257 - { id: 0, class: _ } 258 - { id: 1, class: _ } 259 - { id: 2, class: _ } 260body: | 261 bb.0.entry: 262 liveins: $w0, $s0 263 ; CHECK-LABEL: name: defaultMappingUseRepairPhysReg 264 ; CHECK: %0:gpr(s32) = COPY $w0 265 ; CHECK-NEXT: %1:fpr(s32) = COPY $s0 266 ; CHECK-NEXT: %3:gpr(s32) = COPY %1 267 ; CHECK-NEXT: %2:gpr(s32) = G_ADD %0, %3 268 %0(s32) = COPY $w0 269 %1(s32) = COPY $s0 270 %2(s32) = G_ADD %0, %1 271... 272 273--- 274# Make sure we can repair physical register defs. 275name: defaultMappingDefRepairPhysReg 276legalized: true 277registers: 278 - { id: 0, class: _ } 279 - { id: 1, class: _ } 280body: | 281 bb.0.entry: 282 liveins: $w0 283 ; CHECK-LABEL: name: defaultMappingDefRepairPhysReg 284 ; CHECK: %0:gpr(s32) = COPY $w0 285 ; CHECK-NEXT: %1:gpr(s32) = G_ADD %0, %0 286 ; CHECK-NEXT: $s0 = COPY %1 287 %0(s32) = COPY $w0 288 %1(s32) = G_ADD %0, %0 289 $s0 = COPY %1 290... 291 292--- 293# Check that the greedy mode is able to switch the 294# G_OR instruction from fpr to gpr. 295name: greedyMappingOr 296legalized: true 297registers: 298 - { id: 0, class: _ } 299 - { id: 1, class: _ } 300 - { id: 2, class: _ } 301body: | 302 bb.0.entry: 303 liveins: $x0, $x1 304 ; CHECK: %0:gpr(<2 x s32>) = COPY $x0 305 ; CHECK-NEXT: %1:gpr(<2 x s32>) = COPY $x1 306 307 ; Fast mode tries to reuse the source of the copy for the destination. 308 ; Now, the default mapping says that %0 and %1 need to be in FPR. 309 ; The repairing code insert two copies to materialize that. 310 ; FAST-NEXT: %3:fpr(<2 x s32>) = COPY %0 311 ; FAST-NEXT: %4:fpr(<2 x s32>) = COPY %1 312 ; The mapping of G_OR is on FPR. 313 ; FAST-NEXT: %2:fpr(<2 x s32>) = G_OR %3, %4 314 315 ; Greedy mode remapped the instruction on the GPR bank. 316 ; GREEDY-NEXT: %2:gpr(<2 x s32>) = G_OR %0, %1 317 %0(<2 x s32>) = COPY $x0 318 %1(<2 x s32>) = COPY $x1 319 %2(<2 x s32>) = G_OR %0, %1 320... 321 322--- 323# Check that the greedy mode is able to switch the 324# G_OR instruction from fpr to gpr, while still honoring 325# %2 constraint. 326name: greedyMappingOrWithConstraints 327legalized: true 328registers: 329 - { id: 0, class: _ } 330 - { id: 1, class: _ } 331 - { id: 2, class: fpr } 332body: | 333 bb.0.entry: 334 liveins: $x0, $x1 335 ; CHECK-LABEL: name: greedyMappingOrWithConstraints 336 337 ; CHECK: %0:gpr(<2 x s32>) = COPY $x0 338 ; CHECK-NEXT: %1:gpr(<2 x s32>) = COPY $x1 339 340 ; Fast mode tries to reuse the source of the copy for the destination. 341 ; Now, the default mapping says that %0 and %1 need to be in FPR. 342 ; The repairing code insert two copies to materialize that. 343 ; FAST-NEXT: %3:fpr(<2 x s32>) = COPY %0 344 ; FAST-NEXT: %4:fpr(<2 x s32>) = COPY %1 345 ; The mapping of G_OR is on FPR. 346 ; FAST-NEXT: %2:fpr(<2 x s32>) = G_OR %3, %4 347 348 ; Greedy mode remapped the instruction on the GPR bank. 349 ; GREEDY-NEXT: %3:gpr(<2 x s32>) = G_OR %0, %1 350 ; We need to keep %2 into FPR because we do not know anything about it. 351 ; GREEDY-NEXT: %2:fpr(<2 x s32>) = COPY %3 352 %0(<2 x s32>) = COPY $x0 353 %1(<2 x s32>) = COPY $x1 354 %2(<2 x s32>) = G_OR %0, %1 355... 356 357--- 358# CHECK-LABEL: name: ignoreTargetSpecificInst 359name: ignoreTargetSpecificInst 360legalized: true 361# CHECK: registers: 362# CHECK-NEXT: - { id: 0, class: gpr64, preferred-register: '' } 363# CHECK-NEXT: - { id: 1, class: gpr64, preferred-register: '' } 364registers: 365 - { id: 0, class: gpr64 } 366 - { id: 1, class: gpr64 } 367body: | 368 bb.0: 369 liveins: $x0 370 371 ; CHECK: %0:gpr64 = COPY $x0 372 ; CHECK-NEXT: %1:gpr64 = ADDXrr %0, %0 373 ; CHECK-NEXT: $x0 = COPY %1 374 ; CHECK-NEXT: RET_ReallyLR implicit $x0 375 376 %0 = COPY $x0 377 %1 = ADDXrr %0, %0 378 $x0 = COPY %1 379 RET_ReallyLR implicit $x0 380... 381 382--- 383# Check that we set the "regBankSelected" property. 384# CHECK-LABEL: name: regBankSelected_property 385# CHECK: legalized: true 386# CHECK: regBankSelected: true 387name: regBankSelected_property 388legalized: true 389regBankSelected: false 390body: | 391 bb.0: 392... 393 394--- 395# CHECK-LABEL: name: bitcast_s32_gpr 396name: bitcast_s32_gpr 397legalized: true 398 399# CHECK: registers: 400# CHECK-NEXT: - { id: 0, class: gpr, preferred-register: '' } 401# CHECK-NEXT: - { id: 1, class: gpr, preferred-register: '' } 402registers: 403 - { id: 0, class: _ } 404 - { id: 1, class: _ } 405 406# CHECK: body: 407# CHECK: %0:gpr(s32) = COPY $w0 408# CHECK: %1:gpr(s32) = G_BITCAST %0 409body: | 410 bb.0: 411 liveins: $w0 412 413 %0(s32) = COPY $w0 414 %1(s32) = G_BITCAST %0 415... 416 417--- 418# CHECK-LABEL: name: bitcast_s32_fpr 419name: bitcast_s32_fpr 420legalized: true 421 422# CHECK: registers: 423# CHECK-NEXT: - { id: 0, class: fpr, preferred-register: '' } 424# CHECK-NEXT: - { id: 1, class: fpr, preferred-register: '' } 425registers: 426 - { id: 0, class: _ } 427 - { id: 1, class: _ } 428 429# CHECK: body: 430# CHECK: %0:fpr(<2 x s16>) = COPY $s0 431# CHECK: %1:fpr(<2 x s16>) = G_BITCAST %0 432body: | 433 bb.0: 434 liveins: $s0 435 436 %0(<2 x s16>) = COPY $s0 437 %1(<2 x s16>) = G_BITCAST %0 438... 439 440--- 441# CHECK-LABEL: name: bitcast_s32_gpr_fpr 442name: bitcast_s32_gpr_fpr 443legalized: true 444 445# CHECK: registers: 446# CHECK-NEXT: - { id: 0, class: gpr, preferred-register: '' } 447# FAST-NEXT: - { id: 1, class: fpr, preferred-register: '' } 448# GREEDY-NEXT: - { id: 1, class: gpr, preferred-register: '' } 449registers: 450 - { id: 0, class: _ } 451 - { id: 1, class: _ } 452 453# CHECK: body: 454# CHECK: %0:gpr(s32) = COPY $w0 455# FAST: %1:fpr(<2 x s16>) = G_BITCAST %0 456# GREEDY: %1:gpr(<2 x s16>) = G_BITCAST %0 457body: | 458 bb.0: 459 liveins: $w0 460 461 %0(s32) = COPY $w0 462 %1(<2 x s16>) = G_BITCAST %0 463... 464 465--- 466# CHECK-LABEL: name: bitcast_s32_fpr_gpr 467name: bitcast_s32_fpr_gpr 468legalized: true 469registers: 470 - { id: 0, class: _ } 471 - { id: 1, class: _ } 472# CHECK: body: 473# CHECK: %0:fpr(<2 x s16>) = COPY $s0 474# FAST: %1:gpr(s32) = G_BITCAST %0 475# GREEDY: %1:fpr(s32) = G_BITCAST %0 476body: | 477 bb.0: 478 liveins: $s0 479 480 %0(<2 x s16>) = COPY $s0 481 %1(s32) = G_BITCAST %0 482... 483 484--- 485# CHECK-LABEL: name: bitcast_s64_gpr 486name: bitcast_s64_gpr 487legalized: true 488registers: 489 - { id: 0, class: _ } 490 - { id: 1, class: _ } 491# CHECK: body: 492# CHECK: %0:gpr(s64) = COPY $x0 493# CHECK: %1:gpr(s64) = G_BITCAST %0 494body: | 495 bb.0: 496 liveins: $x0 497 498 %0(s64) = COPY $x0 499 %1(s64) = G_BITCAST %0 500... 501 502--- 503# CHECK-LABEL: name: bitcast_s64_fpr 504name: bitcast_s64_fpr 505legalized: true 506registers: 507 - { id: 0, class: _ } 508 - { id: 1, class: _ } 509# CHECK: body: 510# CHECK: %0:fpr(<2 x s32>) = COPY $d0 511# CHECK: %1:fpr(<2 x s32>) = G_BITCAST %0 512body: | 513 bb.0: 514 liveins: $d0 515 516 %0(<2 x s32>) = COPY $d0 517 %1(<2 x s32>) = G_BITCAST %0 518... 519 520--- 521# CHECK-LABEL: name: bitcast_s64_gpr_fpr 522name: bitcast_s64_gpr_fpr 523legalized: true 524registers: 525 - { id: 0, class: _ } 526 - { id: 1, class: _ } 527# CHECK: body: 528# CHECK: %0:gpr(s64) = COPY $x0 529# FAST: %1:fpr(<2 x s32>) = G_BITCAST %0 530# GREEDY: %1:gpr(<2 x s32>) = G_BITCAST %0 531body: | 532 bb.0: 533 liveins: $x0 534 535 %0(s64) = COPY $x0 536 %1(<2 x s32>) = G_BITCAST %0 537... 538 539--- 540# CHECK-LABEL: name: bitcast_s64_fpr_gpr 541name: bitcast_s64_fpr_gpr 542legalized: true 543registers: 544 - { id: 0, class: _ } 545 - { id: 1, class: _ } 546# CHECK: body: 547# CHECK: %0:fpr(<2 x s32>) = COPY $d0 548# FAST: %1:gpr(s64) = G_BITCAST %0 549# GREEDY: %1:fpr(s64) = G_BITCAST %0 550body: | 551 bb.0: 552 liveins: $d0 553 554 %0(<2 x s32>) = COPY $d0 555 %1(s64) = G_BITCAST %0 556... 557 558--- 559# CHECK-LABEL: name: bitcast_s128 560name: bitcast_s128 561legalized: true 562tracksRegLiveness: true 563registers: 564 - { id: 0, class: _} 565 - { id: 1, class: _} 566 - { id: 2, class: _} 567 - { id: 3, class: _} 568# CHECK: %3:fpr(s128) = G_MERGE_VALUES 569# CHECK: %2:fpr(<2 x s64>) = G_BITCAST %3(s128) 570body: | 571 bb.1: 572 liveins: $x0, $x1 573 %0(s64) = COPY $x0 574 %1(s64) = COPY $x1 575 %3(s128) = G_MERGE_VALUES %0(s64), %1(s64) 576 %2(<2 x s64>) = G_BITCAST %3(s128) 577 $q0 = COPY %2(<2 x s64>) 578 RET_ReallyLR implicit $q0 579 580... 581 582--- 583# CHECK-LABEL: name: copy_s128 584# This test checks that we issue the proper mapping 585# for copy of size > 64. 586# The mapping should be the same as G_BITCAST. 587name: copy_s128 588legalized: true 589tracksRegLiveness: true 590registers: 591 - { id: 0, class: _} 592 - { id: 1, class: _} 593 - { id: 2, class: _} 594 - { id: 3, class: _} 595 - { id: 4, class: _} 596# CHECK: %3:fpr(s128) = G_MERGE_VALUES 597# CHECK: %4:fpr(s128) = COPY %3(s128) 598# CHECK-NEXT: %2:fpr(<2 x s64>) = G_BITCAST %4(s128) 599body: | 600 bb.1: 601 liveins: $x0, $x1 602 %0(s64) = COPY $x0 603 %1(s64) = COPY $x1 604 %3(s128) = G_MERGE_VALUES %0(s64), %1(s64) 605 %4(s128) = COPY %3(s128) 606 %2(<2 x s64>) = G_BITCAST %4(s128) 607 $q0 = COPY %2(<2 x s64>) 608 RET_ReallyLR implicit $q0 609 610... 611 612--- 613# CHECK-LABEL: name: copy_s128_from_load 614# This test checks that we issue the proper mapping 615# for copy of size > 64 when the input is neither 616# a physcal register nor a generic register. 617# This used to crash when we moved to the statically 618# computed mapping, because we were assuming non-physregs 619# were generic registers and thus have a type, whereas 620# it is not necessarily the case. 621name: copy_s128_from_load 622legalized: true 623tracksRegLiveness: true 624registers: 625 - { id: 0, class: fpr128} 626 - { id: 1, class: _} 627# CHECK: registers: 628# CHECK: - { id: 0, class: fpr128, preferred-register: '' } 629# CHECK: - { id: 1, class: fpr, preferred-register: '' } 630# CHECK: %1:fpr(s128) = COPY %0 631body: | 632 bb.1: 633 liveins: $x0 634 %0 = LDRQui killed $x0, 0 635 %1(s128) = COPY %0 636 $q0 = COPY %1(s128) 637 RET_ReallyLR implicit $q0 638 639... 640 641--- 642# CHECK-LABEL: name: copy_fp16 643# This test checks that we issue the proper mapping 644# for copy of size == 16 when the destination is a fpr 645# physical register and the source a gpr. 646# We used to crash because we thought that mapping couldn't 647# exist in a copy. 648name: copy_fp16 649legalized: true 650tracksRegLiveness: true 651registers: 652 - { id: 0, class: _} 653 - { id: 1, class: _} 654# CHECK: registers: 655# CHECK: - { id: 0, class: gpr, preferred-register: '' } 656# CHECK: - { id: 1, class: gpr, preferred-register: '' } 657# CHECK: %0:gpr(s32) = COPY $w0 658# CHECK-NEXT: %1:gpr(s16) = G_TRUNC %0(s32) 659body: | 660 bb.1: 661 liveins: $w0 662 %0(s32) = COPY $w0 663 %1(s16) = G_TRUNC %0(s32) 664 $h0 = COPY %1(s16) 665 RET_ReallyLR implicit $h0 666 667... 668 669 670--- 671# Make sure the greedy mode is able to take advantage of the 672# alternative mappings of G_LOAD to coalesce the whole chain 673# of computation on GPR. 674# CHECK-LABEL: name: greedyWithChainOfComputation 675name: greedyWithChainOfComputation 676legalized: true 677registers: 678 - { id: 0, class: _ } 679 - { id: 1, class: _ } 680 - { id: 2, class: _ } 681 - { id: 3, class: _ } 682 - { id: 4, class: _ } 683 - { id: 5, class: _ } 684# No repairing should be necessary for both modes. 685# CHECK: %0:gpr(s64) = COPY $x0 686# CHECK-NEXT: %1:gpr(p0) = COPY $x1 687# FAST-NEXT: %2:fpr(<2 x s32>) = G_BITCAST %0(s64) 688# FAST-NEXT: %3:fpr(<2 x s32>) = G_LOAD %1(p0) :: (load 8 from %ir.addr) 689# FAST-NEXT: %4:fpr(<2 x s32>) = G_OR %2, %3 690# GREEDY-NEXT: %2:gpr(<2 x s32>) = G_BITCAST %0(s64) 691# GREEDY-NEXT: %3:gpr(<2 x s32>) = G_LOAD %1(p0) :: (load 8 from %ir.addr) 692# GREEDY-NEXT: %4:gpr(<2 x s32>) = G_OR %2, %3 693# CHECK-NEXT: %5:gpr(s64) = G_BITCAST %4(<2 x s32>) 694# CHECK-NEXT: $x0 = COPY %5(s64) 695# CHECK-NEXT: RET_ReallyLR implicit $x0 696body: | 697 bb.0: 698 liveins: $x0, $x1 699 700 %0(s64) = COPY $x0 701 %1(p0) = COPY $x1 702 %2(<2 x s32>) = G_BITCAST %0(s64) 703 %3(<2 x s32>) = G_LOAD %1(p0) :: (load 8 from %ir.addr) 704 %4(<2 x s32>) = G_OR %2, %3 705 %5(s64) = G_BITCAST %4(<2 x s32>) 706 $x0 = COPY %5(s64) 707 RET_ReallyLR implicit $x0 708 709... 710 711--- 712# Make sure we map what looks like floating point 713# loads to floating point register bank. 714# CHECK-LABEL: name: floatingPointLoad 715name: floatingPointLoad 716legalized: true 717 718# CHECK: registers: 719# CHECK-NEXT: - { id: 0, class: gpr, preferred-register: '' } 720# CHECK-NEXT: - { id: 1, class: gpr, preferred-register: '' } 721# CHECK-NEXT: - { id: 2, class: fpr, preferred-register: '' } 722# CHECK-NEXT: - { id: 3, class: fpr, preferred-register: '' } 723# CHECK-NEXT: - { id: 4, class: fpr, preferred-register: '' } 724registers: 725 - { id: 0, class: _ } 726 - { id: 1, class: _ } 727 - { id: 2, class: _ } 728 - { id: 3, class: _ } 729 730# No repairing should be necessary for both modes. 731# CHECK: %0:gpr(s64) = COPY $x0 732# CHECK-NEXT: %1:gpr(p0) = COPY $x1 733# CHECK-NEXT: %2:fpr(s64) = G_LOAD %1(p0) :: (load 8 from %ir.addr) 734# %0 has been mapped to GPR, we need to repair to match FPR. 735# CHECK-NEXT: %4:fpr(s64) = COPY %0 736# CHECK-NEXT: %3:fpr(s64) = G_FADD %4, %2 737# CHECK-NEXT: $x0 = COPY %3(s64) 738# CHECK-NEXT: RET_ReallyLR implicit $x0 739 740body: | 741 bb.0: 742 liveins: $x0, $x1 743 744 %0(s64) = COPY $x0 745 %1(p0) = COPY $x1 746 %2(s64) = G_LOAD %1(p0) :: (load 8 from %ir.addr) 747 %3(s64) = G_FADD %0, %2 748 $x0 = COPY %3(s64) 749 RET_ReallyLR implicit $x0 750 751... 752 753--- 754# Make sure we map what looks like floating point 755# stores to floating point register bank. 756# CHECK-LABEL: name: floatingPointStore 757name: floatingPointStore 758legalized: true 759 760# CHECK: registers: 761# CHECK-NEXT: - { id: 0, class: gpr, preferred-register: '' } 762# CHECK-NEXT: - { id: 1, class: gpr, preferred-register: '' } 763# CHECK-NEXT: - { id: 2, class: fpr, preferred-register: '' } 764# CHECK-NEXT: - { id: 3, class: fpr, preferred-register: '' } 765# CHECK-NEXT: - { id: 4, class: fpr, preferred-register: '' } 766registers: 767 - { id: 0, class: _ } 768 - { id: 1, class: _ } 769 - { id: 2, class: _ } 770 771# CHECK: %0:gpr(s64) = COPY $x0 772# CHECK-NEXT: %1:gpr(p0) = COPY $x1 773# %0 has been mapped to GPR, we need to repair to match FPR. 774# CHECK-NEXT: %3:fpr(s64) = COPY %0 775# CHECK-NEXT: %4:fpr(s64) = COPY %0 776# CHECK-NEXT: %2:fpr(s64) = G_FADD %3, %4 777# CHECK-NEXT: G_STORE %2(s64), %1(p0) :: (store 8 into %ir.addr) 778# CHECK-NEXT: RET_ReallyLR 779 780body: | 781 bb.0: 782 liveins: $x0, $x1 783 784 %0(s64) = COPY $x0 785 %1(p0) = COPY $x1 786 %2(s64) = G_FADD %0, %0 787 G_STORE %2(s64), %1(p0) :: (store 8 into %ir.addr) 788 RET_ReallyLR 789 790... 791 792--- 793# Make sure we map FPEXT on FPR register bank. 794# CHECK-LABEL: name: fp16Ext32 795name: fp16Ext32 796alignment: 2 797legalized: true 798# CHECK: registers: 799# CHECK-NEXT: - { id: 0, class: gpr, preferred-register: '' } 800# CHECK-NEXT: - { id: 1, class: gpr, preferred-register: '' } 801# CHECK-NEXT: - { id: 2, class: fpr, preferred-register: '' } 802# CHECK-NEXT: - { id: 3, class: fpr, preferred-register: '' } 803registers: 804 - { id: 0, class: _ } 805 - { id: 1, class: _ } 806 - { id: 2, class: _ } 807# CHECK: %1:gpr(s32) = COPY $w0 808# CHECK-NEXT: %0:gpr(s16) = G_TRUNC %1 809# %0 has been mapped to GPR, we need to repair to match FPR. 810# CHECK-NEXT: %3:fpr(s16) = COPY %0 811# CHECK-NEXT: %2:fpr(s32) = G_FPEXT %3 812# CHECK-NEXT: $s0 = COPY %2 813# CHECK-NEXT: RET_ReallyLR 814 815body: | 816 bb.1: 817 liveins: $w0 818 819 %1(s32) = COPY $w0 820 %0(s16) = G_TRUNC %1(s32) 821 %2(s32) = G_FPEXT %0(s16) 822 $s0 = COPY %2(s32) 823 RET_ReallyLR implicit $s0 824 825... 826 827--- 828# Make sure we map FPEXT on FPR register bank. 829# CHECK-LABEL: name: fp16Ext64 830name: fp16Ext64 831alignment: 2 832legalized: true 833# CHECK: registers: 834# CHECK-NEXT: - { id: 0, class: gpr, preferred-register: '' } 835# CHECK-NEXT: - { id: 1, class: gpr, preferred-register: '' } 836# CHECK-NEXT: - { id: 2, class: fpr, preferred-register: '' } 837# CHECK-NEXT: - { id: 3, class: fpr, preferred-register: '' } 838registers: 839 - { id: 0, class: _ } 840 - { id: 1, class: _ } 841 - { id: 2, class: _ } 842# CHECK: %1:gpr(s32) = COPY $w0 843# CHECK-NEXT: %0:gpr(s16) = G_TRUNC %1 844# %0 has been mapped to GPR, we need to repair to match FPR. 845# CHECK-NEXT: %3:fpr(s16) = COPY %0 846# CHECK-NEXT: %2:fpr(s64) = G_FPEXT %3 847# CHECK-NEXT: $d0 = COPY %2 848# CHECK-NEXT: RET_ReallyLR 849 850body: | 851 bb.1: 852 liveins: $w0 853 854 %1(s32) = COPY $w0 855 %0(s16) = G_TRUNC %1(s32) 856 %2(s64) = G_FPEXT %0(s16) 857 $d0 = COPY %2(s64) 858 RET_ReallyLR implicit $d0 859 860... 861 862--- 863# Make sure we map FPEXT on FPR register bank. 864# CHECK-LABEL: name: fp32Ext64 865name: fp32Ext64 866alignment: 2 867legalized: true 868# CHECK: registers: 869# CHECK-NEXT: - { id: 0, class: gpr, preferred-register: '' } 870# CHECK-NEXT: - { id: 1, class: fpr, preferred-register: '' } 871# CHECK-NEXT: - { id: 2, class: fpr, preferred-register: '' } 872registers: 873 - { id: 0, class: _ } 874 - { id: 1, class: _ } 875# CHECK: %0:gpr(s32) = COPY $w0 876# %0 has been mapped to GPR, we need to repair to match FPR. 877# CHECK-NEXT: %2:fpr(s32) = COPY %0 878# CHECK-NEXT: %1:fpr(s64) = G_FPEXT %2 879# CHECK-NEXT: $d0 = COPY %1 880# CHECK-NEXT: RET_ReallyLR 881body: | 882 bb.1: 883 liveins: $w0 884 885 %0(s32) = COPY $w0 886 %1(s64) = G_FPEXT %0(s32) 887 $d0 = COPY %1(s64) 888 RET_ReallyLR implicit $d0 889 890... 891 892--- 893# Make sure we map FP16 ABI on FPR register bank. 894# CHECK-LABEL: name: passFp16 895# CHECK: registers: 896# CHECK: - { id: 0, class: fpr, preferred-register: '' } 897# CHECK: %0:fpr(s16) = COPY $h0 898# CHECK-NEXT: $h0 = COPY %0(s16) 899name: passFp16 900alignment: 2 901legalized: true 902registers: 903 - { id: 0, class: _ } 904body: | 905 bb.1.entry: 906 liveins: $h0 907 908 %0(s16) = COPY $h0 909 $h0 = COPY %0(s16) 910 RET_ReallyLR implicit $h0 911 912... 913--- 914# Make sure we properly detect fp types through copies. 915# In that example, the copy comes from an ABI lowering of a fp type. 916# CHECK-LABEL: name: passFp16ViaAllocas 917# CHECK: registers: 918# CHECK: - { id: 0, class: fpr, preferred-register: '' } 919# CHECK: - { id: 1, class: gpr, preferred-register: '' } 920# CHECK: - { id: 2, class: fpr, preferred-register: '' } 921# 922# CHECK: %0:fpr(s16) = COPY $h0 923# CHECK-NEXT: %1:gpr(p0) = G_FRAME_INDEX %stack.0.p.addr 924# If we didn't look through the copy for %0, the default mapping 925# would have been on GPR and we would have to insert a copy to move 926# the value away from FPR (h0). 927# CHECK-NEXT: G_STORE %0(s16), %1(p0) :: (store 2 into %ir.p.addr) 928# If we didn't look through the copy for %2, the default mapping 929# would have been on GPR and we would have to insert a copy to move 930# the value to FPR (h0). 931# CHECK-NEXT: %2:fpr(s16) = G_LOAD %1(p0) :: (load 2 from %ir.p.addr) 932# CHECK-NEXT: $h0 = COPY %2(s16) 933name: passFp16ViaAllocas 934alignment: 2 935legalized: true 936tracksRegLiveness: true 937registers: 938 - { id: 0, class: _ } 939 - { id: 1, class: _ } 940 - { id: 2, class: _ } 941frameInfo: 942 maxAlignment: 2 943stack: 944 - { id: 0, name: p.addr, size: 2, alignment: 2, stack-id: 0 } 945body: | 946 bb.1.entry: 947 liveins: $h0 948 949 %0(s16) = COPY $h0 950 %1(p0) = G_FRAME_INDEX %stack.0.p.addr 951 G_STORE %0(s16), %1(p0) :: (store 2 into %ir.p.addr) 952 %2(s16) = G_LOAD %1(p0) :: (load 2 from %ir.p.addr) 953 $h0 = COPY %2(s16) 954 RET_ReallyLR implicit $h0 955 956... 957