Index: include/llvm/CodeGen/MachineOperand.h =================================================================== --- include/llvm/CodeGen/MachineOperand.h +++ include/llvm/CodeGen/MachineOperand.h @@ -593,6 +593,9 @@ /// ChangeToMCSymbol - Replace this operand with a new MC symbol operand. void ChangeToMCSymbol(MCSymbol *Sym); + /// Replace this operand with a frame index. + void ChangeToFrameIndex(int Idx); + /// ChangeToRegister - Replace this operand with a new register operand of /// the specified value. If an operand is known to be an register already, /// the setReg method should be used. Index: lib/CodeGen/MachineInstr.cpp =================================================================== --- lib/CodeGen/MachineInstr.cpp +++ lib/CodeGen/MachineInstr.cpp @@ -175,6 +175,16 @@ Contents.Sym = Sym; } +void MachineOperand::ChangeToFrameIndex(int Idx) { + assert((!isReg() || !isTied()) && + "Cannot change a tied operand into a FrameIndex"); + + removeRegFromUses(); + + OpKind = MO_FrameIndex; + setIndex(Idx); +} + /// ChangeToRegister - Replace this operand with a new register operand of /// the specified value. If an operand is known to be an register already, /// the setReg method should be used. Index: lib/Target/AMDGPU/SIInstrInfo.cpp =================================================================== --- lib/Target/AMDGPU/SIInstrInfo.cpp +++ lib/Target/AMDGPU/SIInstrInfo.cpp @@ -930,16 +930,23 @@ static MachineInstr *swapRegAndNonRegOperand(MachineInstr &MI, MachineOperand &RegOp, MachineOperand &ImmOp) { - // TODO: Handle other immediate like types. - if (!ImmOp.isImm()) + unsigned Reg = RegOp.getReg(); + unsigned SubReg = RegOp.getSubReg(); + bool IsKill = RegOp.isKill(); + bool IsDead = RegOp.isDead(); + bool IsUndef = RegOp.isUndef(); + bool IsDebug = RegOp.isDebug(); + + if (ImmOp.isImm()) + RegOp.ChangeToImmediate(ImmOp.getImm()); + else if (ImmOp.isFI()) + RegOp.ChangeToFrameIndex(ImmOp.getIndex()); + else return nullptr; - int64_t ImmVal = ImmOp.getImm(); - ImmOp.ChangeToRegister(RegOp.getReg(), false, false, - RegOp.isKill(), RegOp.isDead(), RegOp.isUndef(), - RegOp.isDebug()); - ImmOp.setSubReg(RegOp.getSubReg()); - RegOp.ChangeToImmediate(ImmVal); + ImmOp.ChangeToRegister(Reg, false, false, IsKill, IsDead, IsUndef, IsDebug); + ImmOp.setSubReg(SubReg); + return &MI; } Index: test/CodeGen/AMDGPU/commute-compares.ll =================================================================== --- test/CodeGen/AMDGPU/commute-compares.ll +++ test/CodeGen/AMDGPU/commute-compares.ll @@ -693,5 +693,20 @@ ret void } +; Without commuting the frame index in the pre-regalloc run of +; SIShrinkInstructions, this was using the VOP3 compare. + +; GCN-LABEL: {{^}}commute_frameindex: +; GCN: v_cmp_eq_i32_e32 vcc, 0, v{{[0-9]+}} +define void @commute_frameindex(i32 addrspace(1)* nocapture %out) #0 { +entry: + %stack0 = alloca i32 + %ptr0 = load volatile i32*, i32* addrspace(1)* undef + %eq = icmp eq i32* %ptr0, %stack0 + %ext = zext i1 %eq to i32 + store volatile i32 %ext, i32 addrspace(1)* %out + ret void +} + attributes #0 = { nounwind readnone } attributes #1 = { nounwind }