1# RUN: llc -march=amdgcn -mcpu=gfx900 -run-pass si-mode-register %s -o - | FileCheck %s 2 3--- 4# check that the mode is changed to rtz from default rtn for interp f16 5# CHECK-LABEL: name: interp_f16_default 6# CHECK-LABEL: bb.0: 7# CHECK: S_SETREG_IMM32_B32 3, 2177 8# CHECK-NEXT: V_INTERP_P1LL_F16 9# CHECK: S_SETREG_IMM32_B32 0, 2177 10# CHECK-NEXT: V_ADD_F16_e32 11# CHECK-NOT: S_SETREG_IMM32_B32 12 13name: interp_f16_default 14 15body: | 16 bb.0: 17 liveins: $sgpr0, $sgpr1, $sgpr2 18 $m0 = S_MOV_B32 killed $sgpr2 19 $vgpr0 = V_MOV_B32_e32 killed $sgpr0, implicit $exec, implicit $exec 20 $vgpr1 = V_INTERP_P1LL_F16 0, $vgpr0, 2, 1, 0, 0, 0, implicit $mode, implicit $m0, implicit $exec 21 $vgpr2 = V_MOV_B32_e32 killed $sgpr1, implicit $exec 22 $vgpr0 = V_INTERP_P1LL_F16 0, killed $vgpr0, 2, 1, -1, 0, 0, implicit $mode, implicit $m0, implicit $exec 23 $vgpr1 = V_INTERP_P2_F16 0, $vgpr2, 2, 1, 0, killed $vgpr1, 0, 0, implicit $mode, implicit $m0, implicit $exec 24 $vgpr0 = V_INTERP_P2_F16 0, killed $vgpr2, 2, 1, 0, killed $vgpr0, -1, 0, implicit $mode, implicit $m0, implicit $exec 25 $vgpr0 = V_ADD_F16_e32 killed $vgpr1, killed $vgpr0, implicit $mode, implicit $exec 26 S_ENDPGM 0 27... 28--- 29# check that the mode is not changed for interp f16 when the mode is already RTZ 30# CHECK-LABEL: name: interp_f16_explicit_rtz 31# CHECK-LABEL: bb.0: 32# CHECK: S_SETREG_IMM32_B32 3, 2177 33# CHECK-NEXT: V_MOV_B32_e32 34# CHECK: S_SETREG_IMM32_B32 0, 2177 35# CHECK-NEXT: V_ADD_F16_e32 36# CHECK-NOT: S_SETREG_IMM32_B32 37 38name: interp_f16_explicit_rtz 39 40body: | 41 bb.0: 42 liveins: $sgpr0, $sgpr1, $sgpr2 43 $m0 = S_MOV_B32 killed $sgpr2 44 S_SETREG_IMM32_B32 3, 2177, implicit-def $mode, implicit $mode 45 $vgpr0 = V_MOV_B32_e32 killed $sgpr0, implicit $exec, implicit $exec 46 $vgpr1 = V_INTERP_P1LL_F16 0, $vgpr0, 2, 1, 0, 0, 0, implicit $mode, implicit $m0, implicit $exec 47 $vgpr2 = V_MOV_B32_e32 killed $sgpr1, implicit $exec 48 $vgpr0 = V_INTERP_P1LL_F16 0, killed $vgpr0, 2, 1, -1, 0, 0, implicit $mode, implicit $m0, implicit $exec 49 $vgpr1 = V_INTERP_P2_F16 0, $vgpr2, 2, 1, 0, killed $vgpr1, 0, 0, implicit $mode, implicit $m0, implicit $exec 50 $vgpr0 = V_INTERP_P2_F16 0, killed $vgpr2, 2, 1, 0, killed $vgpr0, -1, 0, implicit $mode, implicit $m0, implicit $exec 51 $vgpr0 = V_ADD_F16_e32 killed $vgpr1, killed $vgpr0, implicit $mode, implicit $exec 52 S_ENDPGM 0 53... 54--- 55# check that explicit RTN mode change is registered 56# CHECK-LABEL: name: explicit_rtn 57# CHECK-LABEL: bb.0: 58# CHECK: S_SETREG_IMM32_B32 3, 2177 59# CHECK-NEXT: V_INTERP_P1LL_F16 60# CHECK: S_SETREG_IMM32_B32 0, 2177 61# CHECK-NEXT: V_ADD_F16_e32 62# CHECK-NOT: S_SETREG_IMM32_B32 63 64name: explicit_rtn 65 66body: | 67 bb.0: 68 liveins: $sgpr0, $sgpr1, $sgpr2 69 $m0 = S_MOV_B32 killed $sgpr2 70 $vgpr0 = V_MOV_B32_e32 killed $sgpr0, implicit $exec, implicit $exec 71 $vgpr1 = V_INTERP_P1LL_F16 0, $vgpr0, 2, 1, 0, 0, 0, implicit $mode, implicit $m0, implicit $exec 72 $vgpr2 = V_MOV_B32_e32 killed $sgpr1, implicit $exec 73 $vgpr0 = V_INTERP_P1LL_F16 0, killed $vgpr0, 2, 1, -1, 0, 0, implicit $mode, implicit $m0, implicit $exec 74 $vgpr1 = V_INTERP_P2_F16 0, $vgpr2, 2, 1, 0, killed $vgpr1, 0, 0, implicit $mode, implicit $m0, implicit $exec 75 $vgpr0 = V_INTERP_P2_F16 0, killed $vgpr2, 2, 1, 0, killed $vgpr0, -1, 0, implicit $mode, implicit $m0, implicit $exec 76 S_SETREG_IMM32_B32 0, 2177, implicit-def $mode, implicit $mode 77 $vgpr0 = V_ADD_F16_e32 killed $vgpr1, killed $vgpr0, implicit $mode, implicit $exec 78 S_ENDPGM 0 79... 80--- 81# check that the mode is unchanged from RTN for F64 instruction 82# CHECK-LABEL: name: rtn_default 83# CHECK-LABEL: bb.0: 84# CHECK-NOT: S_SETREG_IMM32_B32 85# CHECK: V_FRACT_F64 86 87name: rtn_default 88 89body: | 90 bb.0: 91 liveins: $vgpr1_vgpr2 92 $vgpr1_vgpr2 = V_FRACT_F64_e32 killed $vgpr1_vgpr2, implicit $mode, implicit $exec 93 S_ENDPGM 0 94... 95--- 96# check that the mode is changed from RTZ to RTN for F64 instruction 97# CHECK-LABEL: name: rtn_from_rtz 98# CHECK-LABEL: bb.0: 99# CHECK: S_SETREG_IMM32_B32 3, 2177 100# CHECK-NEXT: S_SETREG_IMM32_B32 0, 2177 101# CHECK-NEXT: V_FRACT_F64 102# CHECK-NOT: S_SETREG_IMM32_B32 103 104name: rtn_from_rtz 105 106body: | 107 bb.0: 108 liveins: $vgpr1_vgpr2 109 S_SETREG_IMM32_B32 3, 2177, implicit-def $mode, implicit $mode 110 $vgpr1_vgpr2 = V_FRACT_F64_e32 killed $vgpr1_vgpr2, implicit $mode, implicit $exec 111 S_ENDPGM 0 112... 113--- 114# CHECK-LABEL: name: rtz_from_rtn 115# CHECK-LABEL: bb.1: 116# CHECK: S_SETREG_IMM32_B32 3, 2177 117# CHECK-NOT: S_SETREG_IMM32_B32 118 119name: rtz_from_rtn 120 121body: | 122 bb.0: 123 successors: %bb.1 124 liveins: $vgpr1_vgpr2 125 $vgpr1_vgpr2 = V_FRACT_F64_e32 killed $vgpr1_vgpr2, implicit $mode, implicit $exec 126 S_BRANCH %bb.1 127 128 bb.1: 129 $vgpr1 = V_INTERP_P1LL_F16 0, $vgpr0, 2, 1, 0, 0, 0, implicit $mode, implicit $m0, implicit $exec 130 S_ENDPGM 0 131... 132--- 133# check that the mode is changed from RTZ to RTN for F64 instruction 134# and back again for remaining interp instruction 135# CHECK-LABEL: name: interp_f16_plus_sqrt_f64 136# CHECK-LABEL: bb.0: 137# CHECK: S_SETREG_IMM32_B32 3, 2177 138# CHECK: V_INTERP_P1LL_F16 139# CHECK: V_INTERP_P1LL_F16 140# CHECK: V_INTERP_P2_F16 141# CHECK: S_SETREG_IMM32_B32 0, 2177 142# CHECK: V_FRACT_F64 143# CHECK: S_SETREG_IMM32_B32 3, 2177 144# CHECK: V_INTERP_P2_F16 145 146name: interp_f16_plus_sqrt_f64 147 148body: | 149 bb.0: 150 liveins: $sgpr0, $sgpr1, $sgpr2, $vgpr3, $vgpr4 151 $m0 = S_MOV_B32 killed $sgpr2 152 $vgpr0 = V_MOV_B32_e32 $sgpr0, implicit $exec, implicit $exec 153 $vgpr1 = V_INTERP_P1LL_F16 0, $vgpr0, 2, 1, 0, 0, 0, implicit $mode, implicit $m0, implicit $exec 154 $vgpr2 = V_MOV_B32_e32 $sgpr1, implicit $exec, implicit $exec 155 $vgpr0 = V_INTERP_P1LL_F16 0, killed $vgpr0, 2, 1, -1, 0, 0, implicit $mode, implicit $m0, implicit $exec 156 $vgpr1 = V_INTERP_P2_F16 0, $vgpr2, 2, 1, 0, killed $vgpr1, 0, 0, implicit $mode, implicit $m0, implicit $exec 157 $vgpr3_vgpr4 = V_FRACT_F64_e32 killed $vgpr3_vgpr4, implicit $mode, implicit $exec 158 $vgpr0 = V_INTERP_P2_F16 0, killed $vgpr2, 2, 1, 0, killed $vgpr0, -1, 0, implicit $mode, implicit $m0, implicit $exec 159 $vgpr0 = V_ADD_F16_e32 killed $sgpr0, killed $vgpr0, implicit $mode, implicit $exec 160 S_ENDPGM 0 161... 162--- 163# check that an explicit change to the single precision mode has no effect 164# CHECK-LABEL: name: single_precision_mode_change 165# CHECK-LABEL: bb.0: 166# CHECK: S_SETREG_IMM32_B32 3, 2177 167# CHECK: V_INTERP_P1LL_F16 168# CHECK: V_INTERP_P1LL_F16 169# CHECK: V_INTERP_P2_F16 170# CHECK: S_SETREG_IMM32_B32 0, 2177 171# CHECK: V_FRACT_F64 172# CHECK: S_SETREG_IMM32_B32 3, 2177 173# CHECK: V_INTERP_P2_F16 174 175name: single_precision_mode_change 176 177body: | 178 bb.0: 179 liveins: $sgpr0, $sgpr1, $sgpr2, $vgpr3, $vgpr4 180 $m0 = S_MOV_B32 killed $sgpr2 181 $vgpr0 = V_MOV_B32_e32 $sgpr0, implicit $exec, implicit $exec 182 $vgpr1 = V_INTERP_P1LL_F16 0, $vgpr0, 2, 1, 0, 0, 0, implicit $mode, implicit $m0, implicit $exec 183 S_SETREG_IMM32_B32 2, 2049, implicit-def $mode, implicit $mode 184 $vgpr2 = V_MOV_B32_e32 $sgpr1, implicit $exec 185 $vgpr0 = V_INTERP_P1LL_F16 0, killed $vgpr0, 2, 1, -1, 0, 0, implicit $mode, implicit $m0, implicit $exec 186 $vgpr1 = V_INTERP_P2_F16 0, $vgpr2, 2, 1, 0, killed $vgpr1, 0, 0, implicit $mode, implicit $m0, implicit $exec 187 $vgpr3_vgpr4 = V_FRACT_F64_e32 killed $vgpr3_vgpr4, implicit $mode, implicit $exec 188 $vgpr0 = V_INTERP_P2_F16 0, killed $vgpr2, 2, 1, 0, killed $vgpr0, -1, 0, implicit $mode, implicit $m0, implicit $exec 189 $vgpr0 = V_ADD_F16_e32 killed $sgpr0, killed $vgpr0, implicit $mode, implicit $exec 190 S_ENDPGM 0 191... 192--- 193# check that mode is propagated back to start of loop - first instruction is RTN but needs 194# setreg as RTZ is set in loop 195# CHECK-LABEL: name: loop 196# CHECK-LABEL: bb.1: 197# CHECK: S_SETREG_IMM32_B32 0, 2177 198# CHECK: V_FRACT_F64 199# CHECK-LABEL: bb.2: 200# CHECK: S_SETREG_IMM32_B32 3, 2177 201# CHECK: V_INTERP_P1LL_F16 202# CHECK-NOT: S_SETREG_IMM32_B32 203 204name: loop 205 206body: | 207 bb.0: 208 liveins: $sgpr0, $sgpr1, $sgpr2, $vgpr3, $vgpr4 209 successors: %bb.1 210 $m0 = S_MOV_B32 killed $sgpr2 211 S_BRANCH %bb.1 212 213 bb.1: 214 successors: %bb.2 215 $vgpr3_vgpr4 = V_FRACT_F64_e32 killed $vgpr3_vgpr4, implicit $mode, implicit $exec 216 S_BRANCH %bb.2 217 218 bb.2: 219 successors: %bb.1, %bb.3 220 $vgpr0 = V_MOV_B32_e32 $sgpr0, implicit $exec 221 $vgpr1 = V_INTERP_P1LL_F16 0, $vgpr0, 2, 1, 0, 0, 0, implicit $mode, implicit $m0, implicit $exec 222 S_CBRANCH_VCCZ %bb.1, implicit $vcc 223 S_BRANCH %bb.3 224 225 bb.3: 226 S_ENDPGM 0 227... 228--- 229# two back-edges to same node with different modes 230# CHECK-LABEL: name: double_loop 231# CHECK-NOT: S_SETREG_IMM32_B32 232# CHECK-LABEL: bb.2: 233# CHECK: S_SETREG_IMM32_B32 0, 2177 234# CHECK: V_FRACT_F64_e32 235# CHECK-LABEL: bb.4: 236# CHECK: S_SETREG_IMM32_B32 3, 2177 237 238name: double_loop 239 240body: | 241 bb.0: 242 liveins: $sgpr0, $sgpr1, $sgpr2, $vgpr3, $vgpr4 243 successors: %bb.1 244 $m0 = S_MOV_B32 killed $sgpr2 245 S_BRANCH %bb.1 246 247 bb.1: 248 successors: %bb.2 249 S_NOP 1 250 S_BRANCH %bb.2 251 252 bb.2: 253 successors: %bb.1, %bb.3 254 $vgpr3_vgpr4 = V_FRACT_F64_e32 killed $vgpr3_vgpr4, implicit $mode, implicit $exec 255 S_CBRANCH_VCCZ %bb.1, implicit $vcc 256 S_BRANCH %bb.3 257 258 bb.3: 259 successors: %bb.4 260 S_NOP 1 261 S_BRANCH %bb.4 262 263 bb.4: 264 successors: %bb.5 265 S_NOP 1 266 S_BRANCH %bb.5 267 268 bb.5: 269 successors: %bb.1, %bb.6 270 S_SETREG_IMM32_B32 3, 2177, implicit-def $mode, implicit $mode 271 S_CBRANCH_VCCZ %bb.1, implicit $vcc 272 S_BRANCH %bb.6 273 274 bb.6: 275 S_ENDPGM 0 276... 277--- 278# check that mode is propagated back to start of loop and through a block that 279# neither sets or uses the mode. 280# CHECK-LABEL: name: loop_indirect 281# CHECK_NOT: S_SETREG_IMM32_B32 282# CHECK-LABEL: bb.3: 283# CHECK: S_SETREG_IMM32_B32 3, 2177 284# CHECK: V_INTERP_P1LL_F16 285# CHECK-NOT: S_SETREG_IMM32_B32 286 287name: loop_indirect 288 289body: | 290 bb.0: 291 liveins: $sgpr0, $sgpr1, $sgpr2, $vgpr3, $vgpr4 292 successors: %bb.1 293 $m0 = S_MOV_B32 killed $sgpr2 294 S_BRANCH %bb.1 295 296 bb.1: 297 successors: %bb.2 298 S_NOP 1 299 S_BRANCH %bb.2 300 301 bb.2: 302 successors: %bb.3 303 S_NOP 1 304 S_BRANCH %bb.3 305 306 bb.3: 307 successors: %bb.1, %bb.4 308 $vgpr0 = V_MOV_B32_e32 $sgpr0, implicit $exec, implicit $exec 309 $vgpr1 = V_INTERP_P1LL_F16 0, $vgpr0, 2, 1, 0, 0, 0, implicit $mode, implicit $m0, implicit $exec 310 S_CBRANCH_VCCZ %bb.1, implicit $vcc 311 S_BRANCH %bb.4 312 313 bb.4: 314 S_ENDPGM 0 315... 316--- 317# check that multiple mode values are propagated to a block that uses the mode 318# CHECK-LABEL: name: multiple_mode_direct 319# CHECK-LABEL: bb.3: 320# CHECK: S_SETREG_IMM32_B32 0, 2177 321# CHECK: V_FRACT_F64_e32 322# CHECK-NOT: S_SETREG_IMM32_B32 323 324name: multiple_mode_direct 325 326body: | 327 bb.0: 328 liveins: $sgpr0, $sgpr1, $sgpr2, $vgpr3, $vgpr4 329 successors: %bb.1 330 $m0 = S_MOV_B32 killed $sgpr2 331 S_BRANCH %bb.1 332 333 bb.1: 334 successors: %bb.2, %bb.3 335 S_CBRANCH_VCCZ %bb.2, implicit $vcc 336 S_BRANCH %bb.3 337 338 bb.2: 339 successors: %bb.3 340 S_SETREG_IMM32_B32 3, 2177, implicit-def $mode, implicit $mode 341 S_BRANCH %bb.3 342 343 bb.3: 344 successors: %bb.4 345 $vgpr3_vgpr4 = V_FRACT_F64_e32 killed $vgpr3_vgpr4, implicit $mode, implicit $exec 346 S_BRANCH %bb.4 347 348 bb.4: 349 S_ENDPGM 0 350... 351--- 352# check that multiple mode values are propagated through a block that neither 353# sets or uses the mode. 354# CHECK-LABEL: name: multiple_mode_indirect 355# CHECK-LABEL: bb.4: 356# CHECK: S_SETREG_IMM32_B32 0, 2177 357# CHECK: V_FRACT_F64_e32 358# CHECK-NOT: S_SETREG_IMM32_B32 359 360name: multiple_mode_indirect 361 362body: | 363 bb.0: 364 liveins: $sgpr0, $sgpr1, $sgpr2, $vgpr3, $vgpr4 365 successors: %bb.1 366 $m0 = S_MOV_B32 killed $sgpr2 367 S_BRANCH %bb.1 368 369 bb.1: 370 successors: %bb.2, %bb.3 371 S_CBRANCH_VCCZ %bb.2, implicit $vcc 372 S_BRANCH %bb.3 373 374 bb.2: 375 successors: %bb.3 376 S_SETREG_IMM32_B32 3, 2177, implicit-def $mode, implicit $mode 377 S_BRANCH %bb.3 378 379 bb.3: 380 successors: %bb.4 381 S_NOP 1 382 S_BRANCH %bb.4 383 384 bb.4: 385 successors: %bb.5 386 $vgpr3_vgpr4 = V_FRACT_F64_e32 killed $vgpr3_vgpr4, implicit $mode, implicit $exec 387 S_BRANCH %bb.5 388 389 bb.5: 390 S_ENDPGM 0 391... 392--- 393# CHECK-LABEL: name: pass_through_blocks 394# CHECK-LABEL: bb.0: 395# CHECK: V_FRACT_F64_e32 396# CHECK-NEXT: S_SETREG_IMM32_B32 3, 2177 397# CHECK-NOT: S_SETREG_IMM32_B32 398 399name: pass_through_blocks 400 401body: | 402 bb.0: 403 successors: %bb.1 404 liveins: $vgpr1_vgpr2 405 $vgpr1_vgpr2 = V_FRACT_F64_e32 killed $vgpr1_vgpr2, implicit $mode, implicit $exec 406 $vgpr1 = V_INTERP_P1LL_F16 0, $vgpr0, 2, 1, 0, 0, 0, implicit $mode, implicit $m0, implicit $exec 407 S_BRANCH %bb.1 408 409 bb.1: 410 successors: %bb.2 411 S_BRANCH %bb.2 412 413 bb.2: 414 successors: %bb.3 415 S_BRANCH %bb.3 416 417 bb.3: 418 successors: %bb.4 419 S_BRANCH %bb.4 420 421 bb.4: 422 $vgpr1 = V_INTERP_P1LL_F16 0, $vgpr0, 2, 1, 0, 0, 0, implicit $mode, implicit $m0, implicit $exec 423 S_ENDPGM 0 424... 425--- 426# check that multiple mode values are propagated 427# CHECK-LABEL: name: if_then_else 428# CHECK-LABEL: bb.3: 429# CHECK: S_SETREG_IMM32_B32 0, 2177 430# CHECK: V_FRACT_F64_e32 431# CHECK-NOT: S_SETREG_IMM32_B32 432 433name: if_then_else 434 435body: | 436 bb.0: 437 liveins: $sgpr0, $sgpr1, $sgpr2, $vgpr3, $vgpr4 438 successors: %bb.1 439 $m0 = S_MOV_B32 killed $sgpr2 440 S_BRANCH %bb.1 441 442 bb.1: 443 successors: %bb.2, %bb.3 444 S_CBRANCH_VCCZ %bb.3, implicit $vcc 445 S_BRANCH %bb.2 446 447 bb.2: 448 successors: %bb.3 449 S_SETREG_IMM32_B32 3, 2177, implicit-def $mode, implicit $mode 450 S_BRANCH %bb.3 451 452 bb.3: 453 successors: %bb.4 454 $vgpr3_vgpr4 = V_FRACT_F64_e32 killed $vgpr3_vgpr4, implicit $mode, implicit $exec 455 S_BRANCH %bb.4 456 457 bb.4: 458 S_ENDPGM 0 459... 460--- 461# checks for bug where if a block is its own predecessor it could cause mode tracking 462# to produce the wrong mode, resulting in an unnecessary setreg 463# CHECK-LABEL: name: single_block_loop 464# CHECK-LABEL: bb.0: 465# CHECK-NOT: S_SETREG 466 467name: single_block_loop 468 469body: | 470 bb.0: 471 successors: %bb.1 472 S_BRANCH %bb.1 473 474 bb.1: 475 successors: %bb.1, %bb.2 476 S_CBRANCH_VCCZ %bb.1, implicit $vcc 477 S_BRANCH %bb.2 478 479 bb.2: 480 successors: %bb.3 481 liveins: $vgpr1_vgpr2 482 $vgpr1_vgpr2 = V_FRACT_F64_e32 killed $vgpr1_vgpr2, implicit $mode, implicit $exec 483 S_BRANCH %bb.3 484 485 bb.3: 486 S_ENDPGM 0 487... 488--- 489# checks for a bug where if the first block is its own predecessor the initial mode was 490# not correctly propagated, resulting in an unnecessary setreg 491# CHECK-LABEL: name: first_block_loop 492# CHECK-LABEL: bb.0: 493# CHECK-NOT: S_SETREG 494 495name: first_block_loop 496 497body: | 498 bb.0: 499 successors: %bb.0, %bb.1 500 S_CBRANCH_VCCZ %bb.0, implicit $vcc 501 S_BRANCH %bb.1 502 503 bb.1: 504 successors: %bb.2 505 liveins: $vgpr1_vgpr2 506 $vgpr1_vgpr2 = V_FRACT_F64_e32 killed $vgpr1_vgpr2, implicit $mode, implicit $exec 507 S_BRANCH %bb.2 508 509 bb.2: 510 S_ENDPGM 0 511... 512