Index: lib/Target/AMDGPU/SIShrinkInstructions.cpp =================================================================== --- lib/Target/AMDGPU/SIShrinkInstructions.cpp +++ lib/Target/AMDGPU/SIShrinkInstructions.cpp @@ -178,18 +178,18 @@ } // Copy MachineOperand with all flags except setting it as implicit. -static MachineOperand copyRegOperandAsImplicit(const MachineOperand &Orig) { - assert(!Orig.isImplicit()); - return MachineOperand::CreateReg(Orig.getReg(), - Orig.isDef(), - true, - Orig.isKill(), - Orig.isDead(), - Orig.isUndef(), - Orig.isEarlyClobber(), - Orig.getSubReg(), - Orig.isDebug(), - Orig.isInternalRead()); +static void copyFlagsToImplicitVCC(MachineInstr &MI, + const MachineOperand &Orig) { + + for (MachineOperand &Use : MI.implicit_operands()) { + if (Use.getReg() == AMDGPU::VCC) { + // XXX - Should there be a MachineOperand setSrcFlags helper? + // XXX - Is kill safe to preserve? + Use.setIsKill(Orig.isKill()); + Use.setIsUndef(Orig.isUndef()); + return; + } + } } static bool isKImmOperand(const SIInstrInfo *TII, const MachineOperand &Src) { @@ -392,10 +392,9 @@ Inst32.addOperand(*Src2); } else { // In the case of V_CNDMASK_B32_e32, the explicit operand src2 is - // replaced with an implicit read of vcc. - assert(Src2->getReg() == AMDGPU::VCC && - "Unexpected missing register operand"); - Inst32.addOperand(copyRegOperandAsImplicit(*Src2)); + // replaced with an implicit read of vcc. This was already added + // during the initial BuildMI, so find it to preserve the flags. + copyFlagsToImplicitVCC(*Inst32, *Src2); } } Index: test/CodeGen/AMDGPU/cndmask-no-def-vcc.ll =================================================================== --- test/CodeGen/AMDGPU/cndmask-no-def-vcc.ll +++ test/CodeGen/AMDGPU/cndmask-no-def-vcc.ll @@ -25,3 +25,29 @@ bb2: ret void } + +; The undef flag on the condition src must be preserved on the +; implicit vcc use to avoid verifier errors. + +; GCN-LABEL: {{^}}preserve_condition_undef_flag: +; GCN-NOT: vcc +; GCN: v_cndmask_b32_e32 v{{[0-9]+}}, 1.0, v{{[0-9]+}}, vcc +; GCN: v_cndmask_b32_e64 v1, 0, 1, s{{\[[0-9]+:[0-9]+\]}} +define void @preserve_condition_undef_flag(float %arg, i32 %arg1, float %arg2) { +bb0: + %tmp = icmp sgt i32 %arg1, 4 + %tmp4 = select i1 undef, float %arg, float 1.000000e+00 + %tmp5 = fcmp ogt float %arg2, 0.000000e+00 + %tmp6 = fcmp olt float %arg2, 1.000000e+00 + %tmp7 = fcmp olt float %arg, %tmp4 + %tmp8 = and i1 %tmp5, %tmp6 + %tmp9 = and i1 %tmp8, %tmp7 + br i1 %tmp9, label %bb1, label %bb2 + +bb1: + store volatile i32 0, i32 addrspace(1)* undef + br label %bb2 + +bb2: + ret void +}