diff --git a/llvm/lib/Target/AMDGPU/SIInstrInfo.cpp b/llvm/lib/Target/AMDGPU/SIInstrInfo.cpp --- a/llvm/lib/Target/AMDGPU/SIInstrInfo.cpp +++ b/llvm/lib/Target/AMDGPU/SIInstrInfo.cpp @@ -3461,8 +3461,11 @@ Inst32.add(*Src2); } else { // In the case of V_CNDMASK_B32_e32, the explicit operand src2 is - // replaced with an implicit read of vcc. This was already added - // during the initial BuildMI, so find it to preserve the flags. + // replaced with an implicit read of vcc or vcc_lo. The implicit read + // of vcc was already added during the initial BuildMI, but we + // 1) may need to change vcc to vcc_lo to preserve the original register + // 2) have to preserve the original flags. + fixImplicitOperands(*Inst32); copyFlagsToImplicitVCC(*Inst32, *Src2); } } diff --git a/llvm/test/CodeGen/AMDGPU/shrink-instructions-implicit-vcclo.mir b/llvm/test/CodeGen/AMDGPU/shrink-instructions-implicit-vcclo.mir new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/AMDGPU/shrink-instructions-implicit-vcclo.mir @@ -0,0 +1,22 @@ +# RUN: llc -march=amdgcn -mcpu=gfx1010 -run-pass=si-shrink-instructions --verify-machineinstrs %s -o - | FileCheck %s + +# Make sure the implicit vcc_lo of V_CNDMASK is preserved and not promoted to vcc. +--- + +name: shrink_cndmask_implicit_vcc_lo +tracksRegLiveness: true +body: | + bb.0: + liveins: $vgpr0, $vgpr1 + ; CHECK-LABEL: name: shrink_cndmask_implicit_vcc_lo + ; CHECK: [[COPY:%[0-9]+]]:vgpr_32 = COPY $vgpr0 + ; CHECK: [[COPY1:%[0-9]+]]:vgpr_32 = COPY $vgpr0 + ; CHECK: V_CMP_LT_I32_e32 0, [[COPY]], implicit-def $vcc_lo, implicit $exec + ; CHECK: V_CNDMASK_B32_e32 0, [[COPY1]], implicit $vcc_lo, implicit $exec + %0:vgpr_32 = COPY $vgpr0 + %1:vgpr_32 = COPY $vgpr0 + V_CMP_LT_I32_e32 0, %0:vgpr_32, implicit-def $vcc_lo, implicit $exec, implicit-def $vcc + %2:vgpr_32 = V_CNDMASK_B32_e64 0, 0, 0, %1:vgpr_32, $vcc_lo, implicit $exec + S_NOP 0 + +...