MachineOperand &Src1 = MI->getOperand(Src1Idx);
- // Make sure it s legal to commute operands for VOP2.
+ // Make sure it's legal to commute operands for VOP2.
if (isVOP2(MI->getOpcode()) &&
(!isOperandLegal(MI, Src0Idx, &Src1) ||
!isOperandLegal(MI, Src1Idx, &Src0)))
return nullptr;
}
- // XXX: Commute VOP3 instructions with abs and neg set .
- const MachineOperand *Src0Mods = getNamedOperand(*MI,
- AMDGPU::OpName::src0_modifiers);
- const MachineOperand *Src1Mods = getNamedOperand(*MI,
- AMDGPU::OpName::src1_modifiers);
- const MachineOperand *Src2Mods = getNamedOperand(*MI,
- AMDGPU::OpName::src2_modifiers);
-
- if ((Src0Mods && Src0Mods->getImm()) ||
- (Src1Mods && Src1Mods->getImm()) ||
- (Src2Mods && Src2Mods->getImm()))
+ // TODO: Is there any reason to commute with src2 modifiers?
+ // TODO: Should be able to commute with output modifiers just fine.
+ if (hasModifiersSet(*MI, AMDGPU::OpName::src2_modifiers))
return nullptr;
+ // Be sure to copy the source modifiers to the right place.
+ if (MachineOperand *Src0Mods
+ = getNamedOperand(*MI, AMDGPU::OpName::src0_modifiers)) {
+ MachineOperand *Src1Mods
+ = getNamedOperand(*MI, AMDGPU::OpName::src1_modifiers);
+
+ int Src0ModsVal = Src0Mods->getImm();
+ if (!Src1Mods && Src0ModsVal != 0)
+ return nullptr;
+
+ // XXX - This assert might be a lie. It might be useful to have a neg
+ // modifier with 0.0.
+ int Src1ModsVal = Src1Mods->getImm();
+ assert((Src1ModsVal == 0) && "Not expecting modifiers with immediates");
+
+ Src1Mods->setImm(Src0ModsVal);
+ Src0Mods->setImm(Src1ModsVal);
+ }
+
unsigned Reg = Src0.getReg();
unsigned SubReg = Src0.getSubReg();
if (Src1.isImm())
if (!MI->getOperand(Src1Idx).isReg())
return false;
+ // If any source modifiers are set, the generic instruction commuting won't
+ // understand how to copy the source modifiers.
+ if (hasModifiersSet(*MI, AMDGPU::OpName::src0_modifiers) ||
+ hasModifiersSet(*MI, AMDGPU::OpName::src1_modifiers))
+ return false;
+
SrcOpIdx1 = Src0Idx;
SrcOpIdx2 = Src1Idx;
return true;
AMDGPU::OpName::src0_modifiers) != -1;
}
+bool SIInstrInfo::hasModifiersSet(const MachineInstr &MI,
+ unsigned OpName) const {
+ const MachineOperand *Mods = getNamedOperand(MI, OpName);
+ return Mods && Mods->getImm();
+}
+
bool SIInstrInfo::usesConstantBus(const MachineRegisterInfo &MRI,
const MachineOperand &MO) const {
// Literal constants use the constant bus.
}
MachineOperand *SIInstrInfo::getNamedOperand(MachineInstr &MI,
- unsigned OperandName) const {
+ unsigned OperandName) const {
int Idx = AMDGPU::getNamedOperandIdx(MI.getOpcode(), OperandName);
if (Idx == -1)
return nullptr;