| # NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 6 |
| # RUN: llc -mtriple=amdgcn-amd-amdhsa -mcpu=gfx1250 -run-pass=amdgpu-lower-vgpr-encoding -o - %s | FileCheck %s |
| |
| --- |
| # Case 1a: Size < 12 (size=4), imm32[12:19]=0 |
| # S_SET_VGPR_MSB format: (src0_msb[0-1], src1_msb[2-3], src2_msb[4-5], dst_msb[6-7]) |
| # MODE register format: (dst_msb[0-1], src0_msb[2-3], src1_msb[4-5], src2_msb[6-7]) |
| # vgpr256/257 (both MSB=1): S_SET_VGPR_MSB mode = (1 << 0) | (1 << 6) = 65 |
| # MODE register mode = (1 << 0) | (1 << 2) = 5 |
| # New setreg imm = 0x5 | (5 << 12) = 0x5005 = 20485 |
| name: setreg_size_lt_12 |
| tracksRegLiveness: true |
| body: | |
| bb.0: |
| ; CHECK-LABEL: name: setreg_size_lt_12 |
| ; CHECK: S_SET_VGPR_MSB 65, implicit-def $mode |
| ; CHECK-NEXT: $vgpr256 = V_MOV_B32_e32 $vgpr257, implicit $exec |
| ; CHECK-NEXT: S_SETREG_IMM32_B32 20485, 6145, implicit-def $mode, implicit $mode |
| ; CHECK-NEXT: S_ENDPGM 0 |
| $vgpr256 = V_MOV_B32_e32 $vgpr257, implicit $exec |
| ; size=4, offset=0, hwreg=MODE: simm16 = 0x1801 = 6145 |
| S_SETREG_IMM32_B32 5, 6145, implicit-def $mode, implicit $mode |
| S_ENDPGM 0 |
| ... |
| |
| --- |
| # Case 1b: Size == 12 (boundary), imm32[12:19]=0 |
| # vgpr256/257: S_SET_VGPR_MSB mode = 65, MODE register mode = 5 |
| # New setreg imm = 0xABC | (5 << 12) = 0x5ABC = 23228 |
| name: setreg_size_eq_12 |
| tracksRegLiveness: true |
| body: | |
| bb.0: |
| ; CHECK-LABEL: name: setreg_size_eq_12 |
| ; CHECK: S_SET_VGPR_MSB 65, implicit-def $mode |
| ; CHECK-NEXT: $vgpr256 = V_MOV_B32_e32 $vgpr257, implicit $exec |
| ; CHECK-NEXT: S_SETREG_IMM32_B32 23228, 22529, implicit-def $mode, implicit $mode |
| ; CHECK-NEXT: S_ENDPGM 0 |
| $vgpr256 = V_MOV_B32_e32 $vgpr257, implicit $exec |
| ; size=12, offset=0, hwreg=MODE: simm16 = 0x5801 = 22529 |
| S_SETREG_IMM32_B32 2748, 22529, implicit-def $mode, implicit $mode |
| S_ENDPGM 0 |
| ... |
| |
| --- |
| # Case 1c: Size <= 12 with existing non-zero bits in imm32[12:19] |
| # vgpr256/257: S_SET_VGPR_MSB mode = 65, MODE register mode = 5 |
| # imm32 = 0x23005 (bits 12:19 = 0x23), result = 0x5005 = 20485 (bits 12:19 replaced with 5) |
| name: setreg_size_lt_12_nonzero_upper |
| tracksRegLiveness: true |
| body: | |
| bb.0: |
| ; CHECK-LABEL: name: setreg_size_lt_12_nonzero_upper |
| ; CHECK: S_SET_VGPR_MSB 65, implicit-def $mode |
| ; CHECK-NEXT: $vgpr256 = V_MOV_B32_e32 $vgpr257, implicit $exec |
| ; CHECK-NEXT: S_SETREG_IMM32_B32 20485, 6145, implicit-def $mode, implicit $mode |
| ; CHECK-NEXT: S_ENDPGM 0 |
| $vgpr256 = V_MOV_B32_e32 $vgpr257, implicit $exec |
| ; size=4, offset=0, hwreg=MODE: simm16 = 0x1801 = 6145 |
| ; imm32 = 0x23005 = 143365 (bits 12:19 = 0x23) |
| S_SETREG_IMM32_B32 143365, 6145, implicit-def $mode, implicit $mode |
| S_ENDPGM 0 |
| ... |
| |
| --- |
| # Case 2: Size > 12 (size=16), imm32[12:19] already matches VGPR MSBs |
| # vgpr256/257: S_SET_VGPR_MSB mode = 65, MODE register mode = 5 |
| # imm32 = 0x5ABC = 23228 (bits 12:19 = 5), no modification needed |
| name: setreg_size_gt_12_match |
| tracksRegLiveness: true |
| body: | |
| bb.0: |
| ; CHECK-LABEL: name: setreg_size_gt_12_match |
| ; CHECK: S_SET_VGPR_MSB 65, implicit-def $mode |
| ; CHECK-NEXT: $vgpr256 = V_MOV_B32_e32 $vgpr257, implicit $exec |
| ; CHECK-NEXT: S_SETREG_IMM32_B32 23228, 30721, implicit-def $mode, implicit $mode |
| ; CHECK-NEXT: S_ENDPGM 0 |
| $vgpr256 = V_MOV_B32_e32 $vgpr257, implicit $exec |
| ; size=16, offset=0, hwreg=MODE: simm16 = 0x7801 = 30721 |
| ; imm32 = 0x5ABC = 23228 (bits 12:19 = 5 = MODE register mode for vgpr256/257) |
| S_SETREG_IMM32_B32 23228, 30721, implicit-def $mode, implicit $mode |
| S_ENDPGM 0 |
| ... |
| |
| --- |
| # Case 3: Size > 12 (size=16), imm32[12:19] doesn't match VGPR MSBs |
| # vgpr256/257: S_SET_VGPR_MSB mode = 65, MODE register mode = 5 |
| # imm32 = 0x23ABC = 146108 (bits 12:19 = 0x23 != 5), must insert s_set_vgpr_msb after |
| name: setreg_size_gt_12_mismatch |
| tracksRegLiveness: true |
| body: | |
| bb.0: |
| ; CHECK-LABEL: name: setreg_size_gt_12_mismatch |
| ; CHECK: S_SET_VGPR_MSB 65, implicit-def $mode |
| ; CHECK-NEXT: $vgpr256 = V_MOV_B32_e32 $vgpr257, implicit $exec |
| ; CHECK-NEXT: S_SETREG_IMM32_B32 146108, 30721, implicit-def $mode, implicit $mode |
| ; CHECK-NEXT: S_SET_VGPR_MSB 65, implicit-def $mode |
| ; CHECK-NEXT: S_ENDPGM 0 |
| $vgpr256 = V_MOV_B32_e32 $vgpr257, implicit $exec |
| ; size=16, offset=0, hwreg=MODE: simm16 = 0x7801 = 30721 |
| ; imm32 = 0x23ABC = 146108 (bits 12:19 = 0x23 != 5) |
| S_SETREG_IMM32_B32 146108, 30721, implicit-def $mode, implicit $mode |
| S_ENDPGM 0 |
| ... |
| |
| --- |
| # Case 4: Non-MODE hwreg should not be modified |
| # This uses ID_STATUS=2 instead of ID_MODE=1 |
| # vgpr256/257: S_SET_VGPR_MSB mode = 65 |
| name: setreg_non_mode_hwreg |
| tracksRegLiveness: true |
| body: | |
| bb.0: |
| ; CHECK-LABEL: name: setreg_non_mode_hwreg |
| ; CHECK: S_SET_VGPR_MSB 65, implicit-def $mode |
| ; CHECK-NEXT: $vgpr256 = V_MOV_B32_e32 $vgpr257, implicit $exec |
| ; CHECK-NEXT: S_SETREG_IMM32_B32 5, 6146, implicit-def $mode, implicit $mode |
| ; CHECK-NEXT: S_ENDPGM 0 |
| $vgpr256 = V_MOV_B32_e32 $vgpr257, implicit $exec |
| ; size=4, offset=0, hwreg=STATUS(2): simm16 = 2 | (0 << 6) | (3 << 11) = 0x1802 = 6146 |
| S_SETREG_IMM32_B32 5, 6146, implicit-def $mode, implicit $mode |
| S_ENDPGM 0 |
| ... |
| |
| --- |
| # Case 5: Size <= 12 but VGPR MSBs already present (no change needed) |
| # vgpr256/257: S_SET_VGPR_MSB mode = 65, MODE register mode = 5 |
| # imm32 = 0x5005 = 20485 (bits 12:19 = 5 = MODE register mode) |
| name: setreg_size_lt_12_already_correct |
| tracksRegLiveness: true |
| body: | |
| bb.0: |
| ; CHECK-LABEL: name: setreg_size_lt_12_already_correct |
| ; CHECK: S_SET_VGPR_MSB 65, implicit-def $mode |
| ; CHECK-NEXT: $vgpr256 = V_MOV_B32_e32 $vgpr257, implicit $exec |
| ; CHECK-NEXT: S_SETREG_IMM32_B32 20485, 6145, implicit-def $mode, implicit $mode |
| ; CHECK-NEXT: S_ENDPGM 0 |
| $vgpr256 = V_MOV_B32_e32 $vgpr257, implicit $exec |
| ; size=4, offset=0, hwreg=MODE: simm16 = 0x1801 = 6145 |
| ; imm32 = 0x5005 = 20485 (bits 12:19 = 5 = MODE register mode) |
| S_SETREG_IMM32_B32 20485, 6145, implicit-def $mode, implicit $mode |
| S_ENDPGM 0 |
| ... |
| |
| --- |
| # Case 6: Different VGPR MSB value (using different high VGPRs) |
| # vgpr512/513 (both MSB=2): S_SET_VGPR_MSB mode = (2 << 0) | (2 << 6) = 130 |
| # MODE register mode = (2 << 0) | (2 << 2) = 10 |
| # New setreg imm = 0x5 | (10 << 12) = 0xA005 = 40965 |
| name: setreg_different_vgpr_msb |
| tracksRegLiveness: true |
| body: | |
| bb.0: |
| ; CHECK-LABEL: name: setreg_different_vgpr_msb |
| ; CHECK: S_SET_VGPR_MSB 130, implicit-def $mode |
| ; CHECK-NEXT: $vgpr512 = V_MOV_B32_e32 $vgpr513, implicit $exec |
| ; CHECK-NEXT: S_SETREG_IMM32_B32 40965, 6145, implicit-def $mode, implicit $mode |
| ; CHECK-NEXT: S_ENDPGM 0 |
| $vgpr512 = V_MOV_B32_e32 $vgpr513, implicit $exec |
| ; size=4, offset=0, hwreg=MODE: simm16 = 0x1801 = 6145 |
| S_SETREG_IMM32_B32 5, 6145, implicit-def $mode, implicit $mode |
| S_ENDPGM 0 |
| ... |
| |
| --- |
| # Case 7: Piggybacking successfully updates s_setreg_imm32_b32 (Size <= 12) |
| # First VGPR (V_MOV vgpr256, vgpr257): S_SET_VGPR_MSB mode = 65, MODE register mode = 5 |
| # Second VGPR (V_ADD_U32 vgpr256, vgpr257, vgpr512): |
| # S_SET_VGPR_MSB mode = (1 << 0) | (2 << 2) | (1 << 6) = 73 (src0=1, src1=2, dst=1) |
| # MODE register mode = (1 << 0) | (1 << 2) | (2 << 4) = 37 (dst=1, src0=1, src1=2) |
| # Piggybacking updates setreg imm32[12:19] from 5 to 37. |
| # Final setreg imm = 5 | (37 << 12) = 151557 |
| name: setreg_size_le_12_piggyback_superset |
| tracksRegLiveness: true |
| body: | |
| bb.0: |
| ; CHECK-LABEL: name: setreg_size_le_12_piggyback_superset |
| ; CHECK: S_SET_VGPR_MSB 65, implicit-def $mode |
| ; CHECK-NEXT: $vgpr256 = V_MOV_B32_e32 $vgpr257, implicit $exec |
| ; CHECK-NEXT: S_SETREG_IMM32_B32 151557, 6145, implicit-def $mode, implicit $mode |
| ; CHECK-NEXT: $vgpr256 = V_ADD_U32_e32 $vgpr257, $vgpr512, implicit $exec |
| ; CHECK-NEXT: S_ENDPGM 0 |
| $vgpr256 = V_MOV_B32_e32 $vgpr257, implicit $exec |
| ; size=4, offset=0, hwreg=MODE: simm16 = 0x1801 = 6145 |
| S_SETREG_IMM32_B32 5, 6145, implicit-def $mode, implicit $mode |
| ; Second instruction uses same dst/src0 (MSB=1) but adds src1 (MSB=2) |
| $vgpr256 = V_ADD_U32_e32 $vgpr257, $vgpr512, implicit $exec |
| S_ENDPGM 0 |
| ... |
| |
| --- |
| # Case 8: s_setreg_imm32_b32 (Size <= 12) followed by VGPR with different mode bits |
| # First VGPR (V_MOV vgpr256, vgpr0): S_SET_VGPR_MSB mode = 64, MODE register mode = 1 |
| # Second VGPR (V_MOV vgpr256, vgpr256): S_SET_VGPR_MSB mode = 65, MODE register mode = 5 |
| # Setreg gets MODE mode = 1 from first VGPR. Second VGPR needs different src0 bits, |
| # so a new S_SET_VGPR_MSB is inserted. The new S_SET_VGPR_MSB has mode = 65 | (64 << 8) = 16449. |
| name: setreg_size_le_12_then_different_vgpr |
| tracksRegLiveness: true |
| body: | |
| bb.0: |
| liveins: $vgpr0 |
| |
| ; CHECK-LABEL: name: setreg_size_le_12_then_different_vgpr |
| ; CHECK: liveins: $vgpr0 |
| ; CHECK-NEXT: {{ $}} |
| ; CHECK-NEXT: S_SET_VGPR_MSB 64, implicit-def $mode |
| ; CHECK-NEXT: $vgpr256 = V_MOV_B32_e32 $vgpr0, implicit $exec |
| ; CHECK-NEXT: S_SETREG_IMM32_B32 4101, 6145, implicit-def $mode, implicit $mode |
| ; CHECK-NEXT: S_SET_VGPR_MSB 16449, implicit-def $mode |
| ; CHECK-NEXT: $vgpr256 = V_MOV_B32_e32 $vgpr256, implicit $exec |
| ; CHECK-NEXT: S_ENDPGM 0 |
| $vgpr256 = V_MOV_B32_e32 $vgpr0, implicit $exec |
| ; size=4, offset=0, hwreg=MODE: simm16 = 0x1801 = 6145 |
| S_SETREG_IMM32_B32 5, 6145, implicit-def $mode, implicit $mode |
| $vgpr256 = V_MOV_B32_e32 $vgpr256, implicit $exec |
| S_ENDPGM 0 |
| ... |
| |
| --- |
| # Case 9: After s_setreg_imm32_b32 (Size > 12, matching), new s_set_vgpr_msb needed |
| # First VGPR (vgpr256/257): S_SET_VGPR_MSB mode = 65, MODE register mode = 5 |
| # Setreg has size=16 with imm32[12:19]=5 (matches MODE register mode). |
| # handleSetregMode sets MostRecentModeSet = nullptr (can't piggyback on Size > 12). |
| # Second VGPR (vgpr512/513): S_SET_VGPR_MSB mode = 130, MODE register mode = 10 |
| # Since MostRecentModeSet = nullptr, a new s_set_vgpr_msb is inserted. |
| # New s_set_vgpr_msb imm = NewMode | (OldMode << 8) = 130 | (65 << 8) = 16770 |
| name: setreg_size_gt_12_match_then_different_vgpr |
| tracksRegLiveness: true |
| body: | |
| bb.0: |
| ; CHECK-LABEL: name: setreg_size_gt_12_match_then_different_vgpr |
| ; CHECK: S_SET_VGPR_MSB 65, implicit-def $mode |
| ; CHECK-NEXT: $vgpr256 = V_MOV_B32_e32 $vgpr257, implicit $exec |
| ; CHECK-NEXT: S_SETREG_IMM32_B32 23228, 30721, implicit-def $mode, implicit $mode |
| ; CHECK-NEXT: S_SET_VGPR_MSB 16770, implicit-def $mode |
| ; CHECK-NEXT: $vgpr512 = V_MOV_B32_e32 $vgpr513, implicit $exec |
| ; CHECK-NEXT: S_ENDPGM 0 |
| $vgpr256 = V_MOV_B32_e32 $vgpr257, implicit $exec |
| ; size=16, offset=0, hwreg=MODE: simm16 = 0x7801 = 30721 |
| ; imm32 = 0x5ABC = 23228 (bits 12:19 = 5 = MODE register mode, matches!) |
| S_SETREG_IMM32_B32 23228, 30721, implicit-def $mode, implicit $mode |
| $vgpr512 = V_MOV_B32_e32 $vgpr513, implicit $exec |
| S_ENDPGM 0 |
| ... |