| ; NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 6 | |
| ; RUN: llc -O0 -mtriple=amdgpu9.00-amd-amdhsa -structurizecfg-skip-uniform-regions=1 -stop-after=finalize-isel < %s | FileCheck %s -check-prefix=GFX900 | |
| ; RUN: llc -O0 -mtriple=amdgpu9.0a-amd-amdhsa -structurizecfg-skip-uniform-regions=1 -stop-after=finalize-isel < %s | FileCheck %s -check-prefix=GFX90A | |
| ; Regression tests for cases where uniform PHIs were moved into VGPRs, which | |
| ; failed MIR verification because SI_IF_BREAK requires its operands to have an | |
| ; SGPR class. | |
| define i64 @if_break_mask_shares_constant_with_divergent_phi(i1 %cond) { | |
| ; GFX900-LABEL: name: if_break_mask_shares_constant_with_divergent_phi | |
| ; GFX900: bb.0.entry: | |
| ; GFX900-NEXT: successors: %bb.3(0x40000000), %bb.1(0x40000000) | |
| ; GFX900-NEXT: liveins: $vgpr0 | |
| ; GFX900-NEXT: {{ $}} | |
| ; GFX900-NEXT: [[COPY:%[0-9]+]]:vgpr_32 = COPY $vgpr0 | |
| ; GFX900-NEXT: [[V_AND_B32_e64_:%[0-9]+]]:vgpr_32 = V_AND_B32_e64 1, [[COPY]], implicit $exec | |
| ; GFX900-NEXT: [[V_CMP_EQ_U32_e64_:%[0-9]+]]:sreg_64 = V_CMP_EQ_U32_e64 [[V_AND_B32_e64_]], 1, implicit $exec | |
| ; GFX900-NEXT: [[S_MOV_B64_:%[0-9]+]]:sreg_64 = S_MOV_B64 0 | |
| ; GFX900-NEXT: [[COPY1:%[0-9]+]]:sreg_64 = COPY [[S_MOV_B64_]] | |
| ; GFX900-NEXT: [[COPY2:%[0-9]+]]:sreg_64 = COPY [[V_CMP_EQ_U32_e64_]] | |
| ; GFX900-NEXT: [[S_MOV_B64_1:%[0-9]+]]:sreg_64 = S_MOV_B64 0 | |
| ; GFX900-NEXT: [[S_AND_B64_:%[0-9]+]]:sreg_64 = S_AND_B64 $exec, [[S_MOV_B64_1]], implicit-def dead $scc | |
| ; GFX900-NEXT: $vcc = COPY [[S_AND_B64_]] | |
| ; GFX900-NEXT: [[COPY3:%[0-9]+]]:vreg_64 = COPY [[COPY1]], implicit $exec | |
| ; GFX900-NEXT: S_CBRANCH_VCCNZ %bb.3, implicit $vcc | |
| ; GFX900-NEXT: S_BRANCH %bb.1 | |
| ; GFX900-NEXT: {{ $}} | |
| ; GFX900-NEXT: bb.1.loop: | |
| ; GFX900-NEXT: successors: %bb.2(0x40000000), %bb.1(0x40000000) | |
| ; GFX900-NEXT: {{ $}} | |
| ; GFX900-NEXT: [[PHI:%[0-9]+]]:sreg_64 = PHI [[COPY1]], %bb.0, %2, %bb.1 | |
| ; GFX900-NEXT: [[PHI1:%[0-9]+]]:sreg_64 = PHI [[S_MOV_B64_]], %bb.0, %23, %bb.1 | |
| ; GFX900-NEXT: [[COPY4:%[0-9]+]]:sreg_64 = COPY [[COPY2]] | |
| ; GFX900-NEXT: [[SI_IF_BREAK:%[0-9]+]]:sreg_64 = SI_IF_BREAK [[COPY4]], [[PHI]], implicit-def dead $scc | |
| ; GFX900-NEXT: [[S_MOV_B64_2:%[0-9]+]]:sreg_64 = S_MOV_B64 0 | |
| ; GFX900-NEXT: [[COPY5:%[0-9]+]]:vreg_64 = COPY [[PHI1]], implicit $exec | |
| ; GFX900-NEXT: SI_LOOP [[SI_IF_BREAK]], %bb.1, implicit-def dead $exec, implicit-def dead $scc, implicit $exec | |
| ; GFX900-NEXT: S_BRANCH %bb.2 | |
| ; GFX900-NEXT: {{ $}} | |
| ; GFX900-NEXT: bb.2.done: | |
| ; GFX900-NEXT: successors: %bb.3(0x80000000) | |
| ; GFX900-NEXT: {{ $}} | |
| ; GFX900-NEXT: [[PHI2:%[0-9]+]]:vreg_64 = PHI [[COPY5]], %bb.1 | |
| ; GFX900-NEXT: [[PHI3:%[0-9]+]]:sreg_64 = PHI [[SI_IF_BREAK]], %bb.1 | |
| ; GFX900-NEXT: SI_END_CF [[PHI3]], implicit-def dead $exec, implicit-def dead $scc, implicit $exec | |
| ; GFX900-NEXT: [[COPY6:%[0-9]+]]:vreg_64 = COPY [[PHI2]] | |
| ; GFX900-NEXT: S_BRANCH %bb.3 | |
| ; GFX900-NEXT: {{ $}} | |
| ; GFX900-NEXT: bb.3.UnifiedReturnBlock: | |
| ; GFX900-NEXT: [[PHI4:%[0-9]+]]:vreg_64 = PHI [[COPY3]], %bb.0, [[COPY6]], %bb.2 | |
| ; GFX900-NEXT: [[S_MOV_B32_:%[0-9]+]]:sreg_32 = S_MOV_B32 32 | |
| ; GFX900-NEXT: [[V_LSHRREV_B64_e64_:%[0-9]+]]:vreg_64 = V_LSHRREV_B64_e64 [[S_MOV_B32_]], [[PHI4]], implicit $exec | |
| ; GFX900-NEXT: [[COPY7:%[0-9]+]]:vgpr_32 = COPY [[V_LSHRREV_B64_e64_]].sub0 | |
| ; GFX900-NEXT: [[COPY8:%[0-9]+]]:vgpr_32 = COPY [[PHI4]].sub0 | |
| ; GFX900-NEXT: $vgpr0 = COPY [[COPY8]] | |
| ; GFX900-NEXT: $vgpr1 = COPY [[COPY7]] | |
| ; GFX900-NEXT: SI_RETURN implicit $vgpr0, implicit $vgpr1 | |
| ; | |
| ; GFX90A-LABEL: name: if_break_mask_shares_constant_with_divergent_phi | |
| ; GFX90A: bb.0.entry: | |
| ; GFX90A-NEXT: successors: %bb.3(0x40000000), %bb.1(0x40000000) | |
| ; GFX90A-NEXT: liveins: $vgpr0 | |
| ; GFX90A-NEXT: {{ $}} | |
| ; GFX90A-NEXT: [[COPY:%[0-9]+]]:vgpr_32 = COPY $vgpr0 | |
| ; GFX90A-NEXT: [[V_AND_B32_e64_:%[0-9]+]]:vgpr_32 = V_AND_B32_e64 1, [[COPY]], implicit $exec | |
| ; GFX90A-NEXT: [[V_CMP_EQ_U32_e64_:%[0-9]+]]:sreg_64 = V_CMP_EQ_U32_e64 [[V_AND_B32_e64_]], 1, implicit $exec | |
| ; GFX90A-NEXT: [[S_MOV_B64_:%[0-9]+]]:sreg_64 = S_MOV_B64 0 | |
| ; GFX90A-NEXT: [[COPY1:%[0-9]+]]:sreg_64 = COPY [[S_MOV_B64_]] | |
| ; GFX90A-NEXT: [[COPY2:%[0-9]+]]:sreg_64 = COPY [[V_CMP_EQ_U32_e64_]] | |
| ; GFX90A-NEXT: [[S_MOV_B64_1:%[0-9]+]]:sreg_64 = S_MOV_B64 0 | |
| ; GFX90A-NEXT: [[S_AND_B64_:%[0-9]+]]:sreg_64 = S_AND_B64 $exec, [[S_MOV_B64_1]], implicit-def dead $scc | |
| ; GFX90A-NEXT: $vcc = COPY [[S_AND_B64_]] | |
| ; GFX90A-NEXT: [[COPY3:%[0-9]+]]:vreg_64_align2 = COPY [[COPY1]], implicit $exec | |
| ; GFX90A-NEXT: S_CBRANCH_VCCNZ %bb.3, implicit $vcc | |
| ; GFX90A-NEXT: S_BRANCH %bb.1 | |
| ; GFX90A-NEXT: {{ $}} | |
| ; GFX90A-NEXT: bb.1.loop: | |
| ; GFX90A-NEXT: successors: %bb.2(0x40000000), %bb.1(0x40000000) | |
| ; GFX90A-NEXT: {{ $}} | |
| ; GFX90A-NEXT: [[PHI:%[0-9]+]]:sreg_64 = PHI [[COPY1]], %bb.0, %2, %bb.1 | |
| ; GFX90A-NEXT: [[PHI1:%[0-9]+]]:sreg_64 = PHI [[S_MOV_B64_]], %bb.0, %23, %bb.1 | |
| ; GFX90A-NEXT: [[COPY4:%[0-9]+]]:sreg_64 = COPY [[COPY2]] | |
| ; GFX90A-NEXT: [[SI_IF_BREAK:%[0-9]+]]:sreg_64 = SI_IF_BREAK [[COPY4]], [[PHI]], implicit-def dead $scc | |
| ; GFX90A-NEXT: [[S_MOV_B64_2:%[0-9]+]]:sreg_64 = S_MOV_B64 0 | |
| ; GFX90A-NEXT: [[COPY5:%[0-9]+]]:av_64_align2 = COPY [[PHI1]], implicit $exec | |
| ; GFX90A-NEXT: SI_LOOP [[SI_IF_BREAK]], %bb.1, implicit-def dead $exec, implicit-def dead $scc, implicit $exec | |
| ; GFX90A-NEXT: S_BRANCH %bb.2 | |
| ; GFX90A-NEXT: {{ $}} | |
| ; GFX90A-NEXT: bb.2.done: | |
| ; GFX90A-NEXT: successors: %bb.3(0x80000000) | |
| ; GFX90A-NEXT: {{ $}} | |
| ; GFX90A-NEXT: [[PHI2:%[0-9]+]]:av_64_align2 = PHI [[COPY5]], %bb.1 | |
| ; GFX90A-NEXT: [[PHI3:%[0-9]+]]:sreg_64 = PHI [[SI_IF_BREAK]], %bb.1 | |
| ; GFX90A-NEXT: SI_END_CF [[PHI3]], implicit-def dead $exec, implicit-def dead $scc, implicit $exec | |
| ; GFX90A-NEXT: [[COPY6:%[0-9]+]]:av_64_align2 = COPY [[PHI2]] | |
| ; GFX90A-NEXT: [[COPY7:%[0-9]+]]:vreg_64_align2 = COPY [[COPY6]], implicit $exec | |
| ; GFX90A-NEXT: S_BRANCH %bb.3 | |
| ; GFX90A-NEXT: {{ $}} | |
| ; GFX90A-NEXT: bb.3.UnifiedReturnBlock: | |
| ; GFX90A-NEXT: [[PHI4:%[0-9]+]]:vreg_64_align2 = PHI [[COPY3]], %bb.0, [[COPY7]], %bb.2 | |
| ; GFX90A-NEXT: [[S_MOV_B32_:%[0-9]+]]:sreg_32 = S_MOV_B32 32 | |
| ; GFX90A-NEXT: [[V_LSHRREV_B64_e64_:%[0-9]+]]:vreg_64_align2 = V_LSHRREV_B64_e64 [[S_MOV_B32_]], [[PHI4]], implicit $exec | |
| ; GFX90A-NEXT: [[COPY8:%[0-9]+]]:av_32 = COPY [[V_LSHRREV_B64_e64_]].sub0 | |
| ; GFX90A-NEXT: [[COPY9:%[0-9]+]]:av_32 = COPY [[PHI4]].sub0 | |
| ; GFX90A-NEXT: $vgpr0 = COPY [[COPY9]] | |
| ; GFX90A-NEXT: $vgpr1 = COPY [[COPY8]] | |
| ; GFX90A-NEXT: SI_RETURN implicit $vgpr0, implicit $vgpr1 | |
| entry: | |
| br i1 false, label %join, label %loop | |
| loop: | |
| %q = phi ptr [ addrspacecast (ptr addrspace(4) null to ptr), %entry ], [ null, %loop ] | |
| br i1 %cond, label %done, label %loop | |
| done: | |
| %r = ptrtoaddr ptr %q to i64 | |
| ret i64 %r | |
| join: | |
| ret i64 0 | |
| } | |
| define i64 @divergent_loop_with_bypass(i1 %cond, i64 %val) { | |
| ; GFX900-LABEL: name: divergent_loop_with_bypass | |
| ; GFX900: bb.0.entry: | |
| ; GFX900-NEXT: successors: %bb.3(0x40000000), %bb.1(0x40000000) | |
| ; GFX900-NEXT: liveins: $vgpr0, $vgpr1, $vgpr2 | |
| ; GFX900-NEXT: {{ $}} | |
| ; GFX900-NEXT: [[COPY:%[0-9]+]]:vgpr_32 = COPY $vgpr2 | |
| ; GFX900-NEXT: [[COPY1:%[0-9]+]]:vgpr_32 = COPY $vgpr1 | |
| ; GFX900-NEXT: [[COPY2:%[0-9]+]]:vgpr_32 = COPY $vgpr0 | |
| ; GFX900-NEXT: [[REG_SEQUENCE:%[0-9]+]]:vreg_64 = REG_SEQUENCE [[COPY1]], %subreg.sub0, [[COPY]], %subreg.sub1 | |
| ; GFX900-NEXT: [[V_AND_B32_e64_:%[0-9]+]]:vgpr_32 = V_AND_B32_e64 1, [[COPY2]], implicit $exec | |
| ; GFX900-NEXT: [[V_CMP_EQ_U32_e64_:%[0-9]+]]:sreg_64 = V_CMP_EQ_U32_e64 [[V_AND_B32_e64_]], 1, implicit $exec | |
| ; GFX900-NEXT: [[S_MOV_B64_:%[0-9]+]]:sreg_64 = S_MOV_B64 0 | |
| ; GFX900-NEXT: [[COPY3:%[0-9]+]]:vreg_64 = COPY [[REG_SEQUENCE]] | |
| ; GFX900-NEXT: [[COPY4:%[0-9]+]]:sreg_64 = COPY [[V_CMP_EQ_U32_e64_]] | |
| ; GFX900-NEXT: [[S_MOV_B64_1:%[0-9]+]]:sreg_64 = S_MOV_B64 0 | |
| ; GFX900-NEXT: [[S_AND_B64_:%[0-9]+]]:sreg_64 = S_AND_B64 $exec, [[S_MOV_B64_1]], implicit-def dead $scc | |
| ; GFX900-NEXT: $vcc = COPY [[S_AND_B64_]] | |
| ; GFX900-NEXT: [[V_MOV_B:%[0-9]+]]:vreg_64 = V_MOV_B64_PSEUDO 0, implicit $exec | |
| ; GFX900-NEXT: S_CBRANCH_VCCNZ %bb.3, implicit $vcc | |
| ; GFX900-NEXT: S_BRANCH %bb.1 | |
| ; GFX900-NEXT: {{ $}} | |
| ; GFX900-NEXT: bb.1.loop: | |
| ; GFX900-NEXT: successors: %bb.2(0x40000000), %bb.1(0x40000000) | |
| ; GFX900-NEXT: {{ $}} | |
| ; GFX900-NEXT: [[PHI:%[0-9]+]]:sreg_64 = PHI [[S_MOV_B64_]], %bb.0, %1, %bb.1 | |
| ; GFX900-NEXT: [[COPY5:%[0-9]+]]:sreg_64 = COPY [[COPY4]] | |
| ; GFX900-NEXT: [[SI_IF_BREAK:%[0-9]+]]:sreg_64 = SI_IF_BREAK [[COPY5]], [[PHI]], implicit-def dead $scc | |
| ; GFX900-NEXT: SI_LOOP [[SI_IF_BREAK]], %bb.1, implicit-def dead $exec, implicit-def dead $scc, implicit $exec | |
| ; GFX900-NEXT: S_BRANCH %bb.2 | |
| ; GFX900-NEXT: {{ $}} | |
| ; GFX900-NEXT: bb.2.Flow: | |
| ; GFX900-NEXT: successors: %bb.3(0x80000000) | |
| ; GFX900-NEXT: {{ $}} | |
| ; GFX900-NEXT: [[PHI1:%[0-9]+]]:sreg_64 = PHI [[SI_IF_BREAK]], %bb.1 | |
| ; GFX900-NEXT: SI_END_CF [[PHI1]], implicit-def dead $exec, implicit-def dead $scc, implicit $exec | |
| ; GFX900-NEXT: S_BRANCH %bb.3 | |
| ; GFX900-NEXT: {{ $}} | |
| ; GFX900-NEXT: bb.3.join: | |
| ; GFX900-NEXT: [[PHI2:%[0-9]+]]:vreg_64 = PHI [[V_MOV_B]], %bb.0, [[COPY3]], %bb.2 | |
| ; GFX900-NEXT: [[S_MOV_B32_:%[0-9]+]]:sreg_32 = S_MOV_B32 32 | |
| ; GFX900-NEXT: [[V_LSHRREV_B64_e64_:%[0-9]+]]:vreg_64 = V_LSHRREV_B64_e64 [[S_MOV_B32_]], [[PHI2]], implicit $exec | |
| ; GFX900-NEXT: [[COPY6:%[0-9]+]]:vgpr_32 = COPY [[V_LSHRREV_B64_e64_]].sub0 | |
| ; GFX900-NEXT: [[COPY7:%[0-9]+]]:vgpr_32 = COPY [[PHI2]].sub0 | |
| ; GFX900-NEXT: $vgpr0 = COPY [[COPY7]] | |
| ; GFX900-NEXT: $vgpr1 = COPY [[COPY6]] | |
| ; GFX900-NEXT: SI_RETURN implicit $vgpr0, implicit $vgpr1 | |
| ; | |
| ; GFX90A-LABEL: name: divergent_loop_with_bypass | |
| ; GFX90A: bb.0.entry: | |
| ; GFX90A-NEXT: successors: %bb.3(0x40000000), %bb.1(0x40000000) | |
| ; GFX90A-NEXT: liveins: $vgpr0, $vgpr1, $vgpr2 | |
| ; GFX90A-NEXT: {{ $}} | |
| ; GFX90A-NEXT: [[COPY:%[0-9]+]]:vgpr_32 = COPY $vgpr2 | |
| ; GFX90A-NEXT: [[COPY1:%[0-9]+]]:vgpr_32 = COPY $vgpr1 | |
| ; GFX90A-NEXT: [[COPY2:%[0-9]+]]:vgpr_32 = COPY $vgpr0 | |
| ; GFX90A-NEXT: [[REG_SEQUENCE:%[0-9]+]]:vreg_64_align2 = REG_SEQUENCE [[COPY1]], %subreg.sub0, [[COPY]], %subreg.sub1 | |
| ; GFX90A-NEXT: [[V_AND_B32_e64_:%[0-9]+]]:vgpr_32 = V_AND_B32_e64 1, [[COPY2]], implicit $exec | |
| ; GFX90A-NEXT: [[V_CMP_EQ_U32_e64_:%[0-9]+]]:sreg_64 = V_CMP_EQ_U32_e64 [[V_AND_B32_e64_]], 1, implicit $exec | |
| ; GFX90A-NEXT: [[S_MOV_B64_:%[0-9]+]]:sreg_64 = S_MOV_B64 0 | |
| ; GFX90A-NEXT: [[COPY3:%[0-9]+]]:av_64_align2 = COPY [[REG_SEQUENCE]] | |
| ; GFX90A-NEXT: [[COPY4:%[0-9]+]]:sreg_64 = COPY [[V_CMP_EQ_U32_e64_]] | |
| ; GFX90A-NEXT: [[S_MOV_B64_1:%[0-9]+]]:sreg_64 = S_MOV_B64 0 | |
| ; GFX90A-NEXT: [[S_AND_B64_:%[0-9]+]]:sreg_64 = S_AND_B64 $exec, [[S_MOV_B64_1]], implicit-def dead $scc | |
| ; GFX90A-NEXT: $vcc = COPY [[S_AND_B64_]] | |
| ; GFX90A-NEXT: [[V_MOV_B:%[0-9]+]]:vreg_64_align2 = V_MOV_B64_PSEUDO 0, implicit $exec | |
| ; GFX90A-NEXT: S_CBRANCH_VCCNZ %bb.3, implicit $vcc | |
| ; GFX90A-NEXT: S_BRANCH %bb.1 | |
| ; GFX90A-NEXT: {{ $}} | |
| ; GFX90A-NEXT: bb.1.loop: | |
| ; GFX90A-NEXT: successors: %bb.2(0x40000000), %bb.1(0x40000000) | |
| ; GFX90A-NEXT: {{ $}} | |
| ; GFX90A-NEXT: [[PHI:%[0-9]+]]:sreg_64 = PHI [[S_MOV_B64_]], %bb.0, %1, %bb.1 | |
| ; GFX90A-NEXT: [[COPY5:%[0-9]+]]:sreg_64 = COPY [[COPY4]] | |
| ; GFX90A-NEXT: [[SI_IF_BREAK:%[0-9]+]]:sreg_64 = SI_IF_BREAK [[COPY5]], [[PHI]], implicit-def dead $scc | |
| ; GFX90A-NEXT: SI_LOOP [[SI_IF_BREAK]], %bb.1, implicit-def dead $exec, implicit-def dead $scc, implicit $exec | |
| ; GFX90A-NEXT: S_BRANCH %bb.2 | |
| ; GFX90A-NEXT: {{ $}} | |
| ; GFX90A-NEXT: bb.2.Flow: | |
| ; GFX90A-NEXT: successors: %bb.3(0x80000000) | |
| ; GFX90A-NEXT: {{ $}} | |
| ; GFX90A-NEXT: [[PHI1:%[0-9]+]]:sreg_64 = PHI [[SI_IF_BREAK]], %bb.1 | |
| ; GFX90A-NEXT: SI_END_CF [[PHI1]], implicit-def dead $exec, implicit-def dead $scc, implicit $exec | |
| ; GFX90A-NEXT: [[COPY6:%[0-9]+]]:vreg_64_align2 = COPY [[COPY3]], implicit $exec | |
| ; GFX90A-NEXT: S_BRANCH %bb.3 | |
| ; GFX90A-NEXT: {{ $}} | |
| ; GFX90A-NEXT: bb.3.join: | |
| ; GFX90A-NEXT: [[PHI2:%[0-9]+]]:vreg_64_align2 = PHI [[V_MOV_B]], %bb.0, [[COPY6]], %bb.2 | |
| ; GFX90A-NEXT: [[S_MOV_B32_:%[0-9]+]]:sreg_32 = S_MOV_B32 32 | |
| ; GFX90A-NEXT: [[V_LSHRREV_B64_e64_:%[0-9]+]]:vreg_64_align2 = V_LSHRREV_B64_e64 [[S_MOV_B32_]], [[PHI2]], implicit $exec | |
| ; GFX90A-NEXT: [[COPY7:%[0-9]+]]:av_32 = COPY [[V_LSHRREV_B64_e64_]].sub0 | |
| ; GFX90A-NEXT: [[COPY8:%[0-9]+]]:av_32 = COPY [[PHI2]].sub0 | |
| ; GFX90A-NEXT: $vgpr0 = COPY [[COPY8]] | |
| ; GFX90A-NEXT: $vgpr1 = COPY [[COPY7]] | |
| ; GFX90A-NEXT: SI_RETURN implicit $vgpr0, implicit $vgpr1 | |
| entry: | |
| br i1 false, label %join, label %loop | |
| loop: | |
| br i1 %cond, label %join, label %loop | |
| join: | |
| %r = phi i64 [ 0, %entry ], [ %val, %loop ] | |
| ret i64 %r | |
| } |