mirror of
https://github.com/RPCSX/llvm.git
synced 2025-02-14 17:57:43 +00:00
AMDGPU: Preserve undef flag on vcc when shrinking v_cndmask_b32
The implicit operand is added by the initial instruction construction, so this was adding an additional vcc use. The original one was missing the undef flag the original condition had, so the verifier would complain. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@273182 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
17f22f98eb
commit
b2902b2eb0
@ -178,18 +178,16 @@ static void foldImmediates(MachineInstr &MI, const SIInstrInfo *TII,
|
||||
}
|
||||
|
||||
// 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) {
|
||||
@ -392,10 +390,9 @@ bool SIShrinkInstructions::runOnMachineFunction(MachineFunction &MF) {
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,8 @@
|
||||
; 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]+}}
|
||||
@ -25,3 +27,30 @@ bb1:
|
||||
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
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user