diff --git a/llvm/lib/Target/EraVM/EraVMCombineAddressingMode.cpp b/llvm/lib/Target/EraVM/EraVMCombineAddressingMode.cpp index c8e311ed6c3c..0e9d41fdcd66 100644 --- a/llvm/lib/Target/EraVM/EraVMCombineAddressingMode.cpp +++ b/llvm/lib/Target/EraVM/EraVMCombineAddressingMode.cpp @@ -198,17 +198,21 @@ void EraVMCombineAddressingMode::mergeSelect( *Base.getParent(), Base, Base.getDebugLoc(), TII->get(IsIn0 ? In0Map[Base.getOpcode()] : In1Map[Base.getOpcode()])); EraVM::copyOperands(NewMI, Base.operands_begin(), EraVM::in0Iterator(Base)); - if (IsIn0) + if (IsIn0) { EraVM::copyOperands(NewMI, In); - else + EraVM::copyOperands(NewMI, EraVM::in1Range(Base)); + } else { EraVM::copyOperands(NewMI, EraVM::in0Range(Base)); - if (!IsIn0) EraVM::copyOperands(NewMI, In); - else - EraVM::copyOperands(NewMI, EraVM::in1Iterator(Base), - Base.operands_begin() + Base.getNumExplicitOperands() - - 1); - NewMI.add(Base.getOperand(Base.getNumExplicitOperands() - 1)); + } + + // Copy the rest of the operands. For select with register output it will be + // only condition code operand, whereas for stack output it will also be the + // output operand. + EraVM::copyOperands(NewMI, + EraVM::in1Iterator(Base) + + argumentSize(EraVM::ArgumentKind::In1, Base), + Base.operands_begin() + Base.getNumExplicitOperands()); } static bool areEqualStackSlots(MachineInstr::const_mop_iterator It1, diff --git a/llvm/test/CodeGen/EraVM/def-spill.ll b/llvm/test/CodeGen/EraVM/def-spill.ll index e5610443e9ee..eff33921ca1a 100644 --- a/llvm/test/CodeGen/EraVM/def-spill.ll +++ b/llvm/test/CodeGen/EraVM/def-spill.ll @@ -17,6 +17,36 @@ define i256 @spill_addr(i256 %a, i256 %b) nounwind { ret i256 %res } +; CHECK-LABEL: spill_addr_selirs_use +define i256 @spill_addr_selirs_use(i256 %a, i256 %b, i1 %cond) nounwind { + %slot = alloca i256 + ; CHECK: add r1, r2, stack-[1] + %x = add i256 %a, %b + ; CHECK: sub! r3, r0, r0 + ; CHECK: add stack-[1], r0, stack-[2] + ; CHECK: add.ne 1234, r0, stack-[2] + %sel = select i1 %cond, i256 1234, i256 %x + store i256 %sel, i256* %slot + %c = call i256 @foo() + %res = add i256 %x, %c + ret i256 %res +} + +; CHECK-LABEL: spill_addr_selris_use +define i256 @spill_addr_selris_use(i256 %a, i256 %b, i1 %cond) nounwind { + %slot = alloca i256 + ; CHECK: add r1, r2, stack-[1] + %x = add i256 %a, %b + ; CHECK: sub! r3, r0, r0 + ; CHECK: add 1234, r0, stack-[2] + ; CHECK: add.ne stack-[1], r0, stack-[2] + %sel = select i1 %cond, i256 %x, i256 1234 + store i256 %sel, i256* %slot + %c = call i256 @foo() + %res = add i256 %x, %c + ret i256 %res +} + ; CHECK-LABEL: spill_addi define i256 @spill_addi(i256 %a) nounwind { ; TODO: CPR-1221 add 42, r2, stack-[1] diff --git a/llvm/test/CodeGen/EraVM/reload-use.ll b/llvm/test/CodeGen/EraVM/reload-use.ll index 70db70c47359..ac27f3ff5dc6 100644 --- a/llvm/test/CodeGen/EraVM/reload-use.ll +++ b/llvm/test/CodeGen/EraVM/reload-use.ll @@ -420,6 +420,30 @@ define i256 @spill_select(i256 %a, i1 %cond) nounwind { ret i256 %res } +; CHECK-LABEL: spill_selrrs1 +define void @spill_selrrs1(i256 %a, i1 %cond) nounwind { + %slot = alloca i256 + %b = call i256 @foo() +; CHECK: sub! stack-[1], r0, r0 +; CHECK: add r1, r0, stack-[3] +; CHECK: add.ne stack-[2], r0, stack-[3] + %sel = select i1 %cond, i256 %a, i256 %b + store i256 %sel, i256* %slot + ret void +} + +; CHECK-LABEL: spill_selrrs2 +define void @spill_selrrs2(i256 %a, i1 %cond) nounwind { + %slot = alloca i256 + %b = call i256 @foo() +; CHECK: sub! stack-[1], r0, r0 +; CHECK: add stack-[2], r0, stack-[3] +; CHECK: add.ne r1, r0, stack-[3] + %sel = select i1 %cond, i256 %b, i256 %a + store i256 %sel, i256* %slot + ret void +} + ; ============================================================================== ; CHECK-LABEL: spill_multiple_use define void @spill_multiple_use(i256 %a) nounwind {