}
// 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) {
+ Use.setIsUndef(Orig.isUndef());
+ Use.setIsKill(Orig.isKill());
+ return;
+ }
+ }
}
static bool isKImmOperand(const SIInstrInfo *TII, const MachineOperand &Src) {
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);
}
}
; RUN: llc -march=amdgcn -verify-machineinstrs < %s | FileCheck -check-prefix=GCN %s
-; Produces error after adding an implicit deff to v_cndmask_b32
+declare i1 @llvm.amdgcn.class.f32(float, i32)
+
+; Produces error after adding an implicit def to v_cndmask_b32
; GCN-LABEL: {{^}}vcc_shrink_vcc_def:
; GCN: v_cmp_eq_i32_e64 vcc, 0, s{{[0-9]+}}
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
+ %undef = call i1 @llvm.amdgcn.class.f32(float undef, i32 undef)
+ %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
+}