From 39a892bee182d57815283ecc414c8d89d8f6be4c Mon Sep 17 00:00:00 2001 From: Alex Bradbury Date: Wed, 29 Nov 2023 14:56:36 +0000 Subject: [PATCH] [RISCV] Support FrameIndex operands in getMemOperandsWithOffsetWidth / getMemOperandWithOffsetWidth I noted AArch64 happily accepts a FrameIndex operand as well as a register. This doesn't cause any changes outside of my C++ unit test for the current state of in-tree, but this will cause additional test changes if #73789 is rebased on top of it. Note that the returned Offset doesn't seem at all as meaningful if you hae a FrameIndex base, though the approach taken here follows AArch64 (see D54847). This change won't harm the approach taken in shouldClusterMemOps because memOpsHaveSameBasePtr will only return true if the FrameIndex operand is the same for both operations. --- llvm/lib/Target/RISCV/RISCVInstrInfo.cpp | 3 +- ...calling-conv-ilp32-ilp32f-ilp32d-common.ll | 12 ++--- .../calling-conv-lp64-lp64f-lp64d-common.ll | 12 ++--- llvm/test/CodeGen/RISCV/push-pop-popret.ll | 18 ++++---- llvm/test/CodeGen/RISCV/vararg.ll | 44 +++++++++---------- .../Target/RISCV/RISCVInstrInfoTest.cpp | 9 +++- 6 files changed, 52 insertions(+), 46 deletions(-) diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp b/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp index 2918e5654db4f9..8d79fc44a208ea 100644 --- a/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp +++ b/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp @@ -2304,7 +2304,8 @@ bool RISCVInstrInfo::getMemOperandWithOffsetWidth( // load/store instructions. if (LdSt.getNumExplicitOperands() != 3) return false; - if (!LdSt.getOperand(1).isReg() || !LdSt.getOperand(2).isImm()) + if ((!LdSt.getOperand(1).isReg() && !LdSt.getOperand(1).isFI()) || + !LdSt.getOperand(2).isImm()) return false; if (!LdSt.hasOneMemOperand()) diff --git a/llvm/test/CodeGen/RISCV/calling-conv-ilp32-ilp32f-ilp32d-common.ll b/llvm/test/CodeGen/RISCV/calling-conv-ilp32-ilp32f-ilp32d-common.ll index 0e4702d13a8cd2..649234efaad903 100644 --- a/llvm/test/CodeGen/RISCV/calling-conv-ilp32-ilp32f-ilp32d-common.ll +++ b/llvm/test/CodeGen/RISCV/calling-conv-ilp32-ilp32f-ilp32d-common.ll @@ -364,8 +364,8 @@ define i32 @caller_large_scalars_exhausted_regs() nounwind { ; RV32I-FPELIM-NEXT: sw zero, 16(sp) ; RV32I-FPELIM-NEXT: sw zero, 52(sp) ; RV32I-FPELIM-NEXT: sw zero, 48(sp) -; RV32I-FPELIM-NEXT: sw zero, 44(sp) -; RV32I-FPELIM-NEXT: li t0, 8 +; RV32I-FPELIM-NEXT: li a0, 8 +; RV32I-FPELIM-NEXT: sw a0, 40(sp) ; RV32I-FPELIM-NEXT: li a0, 1 ; RV32I-FPELIM-NEXT: li a1, 2 ; RV32I-FPELIM-NEXT: li a2, 3 @@ -374,7 +374,7 @@ define i32 @caller_large_scalars_exhausted_regs() nounwind { ; RV32I-FPELIM-NEXT: li a5, 6 ; RV32I-FPELIM-NEXT: li a6, 7 ; RV32I-FPELIM-NEXT: addi a7, sp, 40 -; RV32I-FPELIM-NEXT: sw t0, 40(sp) +; RV32I-FPELIM-NEXT: sw zero, 44(sp) ; RV32I-FPELIM-NEXT: call callee_large_scalars_exhausted_regs@plt ; RV32I-FPELIM-NEXT: lw ra, 60(sp) # 4-byte Folded Reload ; RV32I-FPELIM-NEXT: addi sp, sp, 64 @@ -397,8 +397,8 @@ define i32 @caller_large_scalars_exhausted_regs() nounwind { ; RV32I-WITHFP-NEXT: sw zero, -48(s0) ; RV32I-WITHFP-NEXT: sw zero, -12(s0) ; RV32I-WITHFP-NEXT: sw zero, -16(s0) -; RV32I-WITHFP-NEXT: sw zero, -20(s0) -; RV32I-WITHFP-NEXT: li t0, 8 +; RV32I-WITHFP-NEXT: li a0, 8 +; RV32I-WITHFP-NEXT: sw a0, -24(s0) ; RV32I-WITHFP-NEXT: li a0, 1 ; RV32I-WITHFP-NEXT: li a1, 2 ; RV32I-WITHFP-NEXT: li a2, 3 @@ -407,7 +407,7 @@ define i32 @caller_large_scalars_exhausted_regs() nounwind { ; RV32I-WITHFP-NEXT: li a5, 6 ; RV32I-WITHFP-NEXT: li a6, 7 ; RV32I-WITHFP-NEXT: addi a7, s0, -24 -; RV32I-WITHFP-NEXT: sw t0, -24(s0) +; RV32I-WITHFP-NEXT: sw zero, -20(s0) ; RV32I-WITHFP-NEXT: call callee_large_scalars_exhausted_regs@plt ; RV32I-WITHFP-NEXT: lw ra, 60(sp) # 4-byte Folded Reload ; RV32I-WITHFP-NEXT: lw s0, 56(sp) # 4-byte Folded Reload diff --git a/llvm/test/CodeGen/RISCV/calling-conv-lp64-lp64f-lp64d-common.ll b/llvm/test/CodeGen/RISCV/calling-conv-lp64-lp64f-lp64d-common.ll index adf3630d2a0c9c..c2690d15665e21 100644 --- a/llvm/test/CodeGen/RISCV/calling-conv-lp64-lp64f-lp64d-common.ll +++ b/llvm/test/CodeGen/RISCV/calling-conv-lp64-lp64f-lp64d-common.ll @@ -140,11 +140,11 @@ define i64 @caller_large_scalars() nounwind { ; RV64I-NEXT: sd a0, 0(sp) ; RV64I-NEXT: sd zero, 56(sp) ; RV64I-NEXT: sd zero, 48(sp) -; RV64I-NEXT: sd zero, 40(sp) -; RV64I-NEXT: li a2, 1 +; RV64I-NEXT: li a0, 1 +; RV64I-NEXT: sd a0, 32(sp) ; RV64I-NEXT: addi a0, sp, 32 ; RV64I-NEXT: mv a1, sp -; RV64I-NEXT: sd a2, 32(sp) +; RV64I-NEXT: sd zero, 40(sp) ; RV64I-NEXT: call callee_large_scalars@plt ; RV64I-NEXT: ld ra, 72(sp) # 8-byte Folded Reload ; RV64I-NEXT: addi sp, sp, 80 @@ -199,8 +199,8 @@ define i64 @caller_large_scalars_exhausted_regs() nounwind { ; RV64I-NEXT: sd a0, 16(sp) ; RV64I-NEXT: sd zero, 72(sp) ; RV64I-NEXT: sd zero, 64(sp) -; RV64I-NEXT: sd zero, 56(sp) -; RV64I-NEXT: li t0, 8 +; RV64I-NEXT: li a0, 8 +; RV64I-NEXT: sd a0, 48(sp) ; RV64I-NEXT: li a0, 1 ; RV64I-NEXT: li a1, 2 ; RV64I-NEXT: li a2, 3 @@ -209,7 +209,7 @@ define i64 @caller_large_scalars_exhausted_regs() nounwind { ; RV64I-NEXT: li a5, 6 ; RV64I-NEXT: li a6, 7 ; RV64I-NEXT: addi a7, sp, 48 -; RV64I-NEXT: sd t0, 48(sp) +; RV64I-NEXT: sd zero, 56(sp) ; RV64I-NEXT: call callee_large_scalars_exhausted_regs@plt ; RV64I-NEXT: ld ra, 88(sp) # 8-byte Folded Reload ; RV64I-NEXT: addi sp, sp, 96 diff --git a/llvm/test/CodeGen/RISCV/push-pop-popret.ll b/llvm/test/CodeGen/RISCV/push-pop-popret.ll index 454d85166435f7..9ff4235746caf0 100644 --- a/llvm/test/CodeGen/RISCV/push-pop-popret.ll +++ b/llvm/test/CodeGen/RISCV/push-pop-popret.ll @@ -1018,13 +1018,13 @@ define i32 @varargs(ptr %fmt, ...) nounwind { ; RV64IZCMP-NEXT: sd a1, 24(sp) ; RV64IZCMP-NEXT: sd a7, 72(sp) ; RV64IZCMP-NEXT: sd a6, 64(sp) +; RV64IZCMP-NEXT: addi a0, sp, 28 +; RV64IZCMP-NEXT: sd a0, 8(sp) +; RV64IZCMP-NEXT: lw a0, 24(sp) ; RV64IZCMP-NEXT: sd a5, 56(sp) ; RV64IZCMP-NEXT: sd a4, 48(sp) ; RV64IZCMP-NEXT: sd a3, 40(sp) ; RV64IZCMP-NEXT: sd a2, 32(sp) -; RV64IZCMP-NEXT: addi a0, sp, 28 -; RV64IZCMP-NEXT: sd a0, 8(sp) -; RV64IZCMP-NEXT: lw a0, 24(sp) ; RV64IZCMP-NEXT: addi sp, sp, 80 ; RV64IZCMP-NEXT: ret ; @@ -1050,13 +1050,13 @@ define i32 @varargs(ptr %fmt, ...) nounwind { ; RV64IZCMP-SR-NEXT: sd a1, 24(sp) ; RV64IZCMP-SR-NEXT: sd a7, 72(sp) ; RV64IZCMP-SR-NEXT: sd a6, 64(sp) +; RV64IZCMP-SR-NEXT: addi a0, sp, 28 +; RV64IZCMP-SR-NEXT: sd a0, 8(sp) +; RV64IZCMP-SR-NEXT: lw a0, 24(sp) ; RV64IZCMP-SR-NEXT: sd a5, 56(sp) ; RV64IZCMP-SR-NEXT: sd a4, 48(sp) ; RV64IZCMP-SR-NEXT: sd a3, 40(sp) ; RV64IZCMP-SR-NEXT: sd a2, 32(sp) -; RV64IZCMP-SR-NEXT: addi a0, sp, 28 -; RV64IZCMP-SR-NEXT: sd a0, 8(sp) -; RV64IZCMP-SR-NEXT: lw a0, 24(sp) ; RV64IZCMP-SR-NEXT: addi sp, sp, 80 ; RV64IZCMP-SR-NEXT: ret ; @@ -1082,13 +1082,13 @@ define i32 @varargs(ptr %fmt, ...) nounwind { ; RV64I-NEXT: sd a1, 24(sp) ; RV64I-NEXT: sd a7, 72(sp) ; RV64I-NEXT: sd a6, 64(sp) +; RV64I-NEXT: addi a0, sp, 28 +; RV64I-NEXT: sd a0, 8(sp) +; RV64I-NEXT: lw a0, 24(sp) ; RV64I-NEXT: sd a5, 56(sp) ; RV64I-NEXT: sd a4, 48(sp) ; RV64I-NEXT: sd a3, 40(sp) ; RV64I-NEXT: sd a2, 32(sp) -; RV64I-NEXT: addi a0, sp, 28 -; RV64I-NEXT: sd a0, 8(sp) -; RV64I-NEXT: lw a0, 24(sp) ; RV64I-NEXT: addi sp, sp, 80 ; RV64I-NEXT: ret %va = alloca ptr diff --git a/llvm/test/CodeGen/RISCV/vararg.ll b/llvm/test/CodeGen/RISCV/vararg.ll index cbed059e12c2ef..67d1bfac4d614b 100644 --- a/llvm/test/CodeGen/RISCV/vararg.ll +++ b/llvm/test/CodeGen/RISCV/vararg.ll @@ -104,13 +104,13 @@ define i32 @va1(ptr %fmt, ...) { ; LP64-LP64F-LP64D-FPELIM-NEXT: sd a1, 24(sp) ; LP64-LP64F-LP64D-FPELIM-NEXT: sd a7, 72(sp) ; LP64-LP64F-LP64D-FPELIM-NEXT: sd a6, 64(sp) +; LP64-LP64F-LP64D-FPELIM-NEXT: addi a0, sp, 28 +; LP64-LP64F-LP64D-FPELIM-NEXT: sd a0, 8(sp) +; LP64-LP64F-LP64D-FPELIM-NEXT: lw a0, 24(sp) ; LP64-LP64F-LP64D-FPELIM-NEXT: sd a5, 56(sp) ; LP64-LP64F-LP64D-FPELIM-NEXT: sd a4, 48(sp) ; LP64-LP64F-LP64D-FPELIM-NEXT: sd a3, 40(sp) ; LP64-LP64F-LP64D-FPELIM-NEXT: sd a2, 32(sp) -; LP64-LP64F-LP64D-FPELIM-NEXT: addi a0, sp, 28 -; LP64-LP64F-LP64D-FPELIM-NEXT: sd a0, 8(sp) -; LP64-LP64F-LP64D-FPELIM-NEXT: lw a0, 24(sp) ; LP64-LP64F-LP64D-FPELIM-NEXT: addi sp, sp, 80 ; LP64-LP64F-LP64D-FPELIM-NEXT: ret ; @@ -127,13 +127,13 @@ define i32 @va1(ptr %fmt, ...) { ; LP64-LP64F-LP64D-WITHFP-NEXT: sd a1, 8(s0) ; LP64-LP64F-LP64D-WITHFP-NEXT: sd a7, 56(s0) ; LP64-LP64F-LP64D-WITHFP-NEXT: sd a6, 48(s0) +; LP64-LP64F-LP64D-WITHFP-NEXT: addi a0, s0, 12 +; LP64-LP64F-LP64D-WITHFP-NEXT: sd a0, -24(s0) +; LP64-LP64F-LP64D-WITHFP-NEXT: lw a0, 8(s0) ; LP64-LP64F-LP64D-WITHFP-NEXT: sd a5, 40(s0) ; LP64-LP64F-LP64D-WITHFP-NEXT: sd a4, 32(s0) ; LP64-LP64F-LP64D-WITHFP-NEXT: sd a3, 24(s0) ; LP64-LP64F-LP64D-WITHFP-NEXT: sd a2, 16(s0) -; LP64-LP64F-LP64D-WITHFP-NEXT: addi a0, s0, 12 -; LP64-LP64F-LP64D-WITHFP-NEXT: sd a0, -24(s0) -; LP64-LP64F-LP64D-WITHFP-NEXT: lw a0, 8(s0) ; LP64-LP64F-LP64D-WITHFP-NEXT: ld ra, 24(sp) # 8-byte Folded Reload ; LP64-LP64F-LP64D-WITHFP-NEXT: ld s0, 16(sp) # 8-byte Folded Reload ; LP64-LP64F-LP64D-WITHFP-NEXT: addi sp, sp, 96 @@ -1773,18 +1773,6 @@ define i32 @va_large_stack(ptr %fmt, ...) { ; LP64-LP64F-LP64D-FPELIM-NEXT: add a0, sp, a0 ; LP64-LP64F-LP64D-FPELIM-NEXT: sd a6, 320(a0) ; LP64-LP64F-LP64D-FPELIM-NEXT: lui a0, 24414 -; LP64-LP64F-LP64D-FPELIM-NEXT: add a0, sp, a0 -; LP64-LP64F-LP64D-FPELIM-NEXT: sd a5, 312(a0) -; LP64-LP64F-LP64D-FPELIM-NEXT: lui a0, 24414 -; LP64-LP64F-LP64D-FPELIM-NEXT: add a0, sp, a0 -; LP64-LP64F-LP64D-FPELIM-NEXT: sd a4, 304(a0) -; LP64-LP64F-LP64D-FPELIM-NEXT: lui a0, 24414 -; LP64-LP64F-LP64D-FPELIM-NEXT: add a0, sp, a0 -; LP64-LP64F-LP64D-FPELIM-NEXT: sd a3, 296(a0) -; LP64-LP64F-LP64D-FPELIM-NEXT: lui a0, 24414 -; LP64-LP64F-LP64D-FPELIM-NEXT: add a0, sp, a0 -; LP64-LP64F-LP64D-FPELIM-NEXT: sd a2, 288(a0) -; LP64-LP64F-LP64D-FPELIM-NEXT: lui a0, 24414 ; LP64-LP64F-LP64D-FPELIM-NEXT: addiw a0, a0, 284 ; LP64-LP64F-LP64D-FPELIM-NEXT: add a0, sp, a0 ; LP64-LP64F-LP64D-FPELIM-NEXT: sd a0, 8(sp) @@ -1792,6 +1780,18 @@ define i32 @va_large_stack(ptr %fmt, ...) { ; LP64-LP64F-LP64D-FPELIM-NEXT: add a0, sp, a0 ; LP64-LP64F-LP64D-FPELIM-NEXT: lw a0, 280(a0) ; LP64-LP64F-LP64D-FPELIM-NEXT: lui a1, 24414 +; LP64-LP64F-LP64D-FPELIM-NEXT: add a1, sp, a1 +; LP64-LP64F-LP64D-FPELIM-NEXT: sd a5, 312(a1) +; LP64-LP64F-LP64D-FPELIM-NEXT: lui a1, 24414 +; LP64-LP64F-LP64D-FPELIM-NEXT: add a1, sp, a1 +; LP64-LP64F-LP64D-FPELIM-NEXT: sd a4, 304(a1) +; LP64-LP64F-LP64D-FPELIM-NEXT: lui a1, 24414 +; LP64-LP64F-LP64D-FPELIM-NEXT: add a1, sp, a1 +; LP64-LP64F-LP64D-FPELIM-NEXT: sd a3, 296(a1) +; LP64-LP64F-LP64D-FPELIM-NEXT: lui a1, 24414 +; LP64-LP64F-LP64D-FPELIM-NEXT: add a1, sp, a1 +; LP64-LP64F-LP64D-FPELIM-NEXT: sd a2, 288(a1) +; LP64-LP64F-LP64D-FPELIM-NEXT: lui a1, 24414 ; LP64-LP64F-LP64D-FPELIM-NEXT: addiw a1, a1, 336 ; LP64-LP64F-LP64D-FPELIM-NEXT: add sp, sp, a1 ; LP64-LP64F-LP64D-FPELIM-NEXT: ret @@ -1812,15 +1812,15 @@ define i32 @va_large_stack(ptr %fmt, ...) { ; LP64-LP64F-LP64D-WITHFP-NEXT: sd a1, 8(s0) ; LP64-LP64F-LP64D-WITHFP-NEXT: sd a7, 56(s0) ; LP64-LP64F-LP64D-WITHFP-NEXT: sd a6, 48(s0) -; LP64-LP64F-LP64D-WITHFP-NEXT: sd a5, 40(s0) -; LP64-LP64F-LP64D-WITHFP-NEXT: sd a4, 32(s0) -; LP64-LP64F-LP64D-WITHFP-NEXT: sd a3, 24(s0) -; LP64-LP64F-LP64D-WITHFP-NEXT: sd a2, 16(s0) ; LP64-LP64F-LP64D-WITHFP-NEXT: addi a0, s0, 12 ; LP64-LP64F-LP64D-WITHFP-NEXT: lui a1, 24414 ; LP64-LP64F-LP64D-WITHFP-NEXT: sub a1, s0, a1 ; LP64-LP64F-LP64D-WITHFP-NEXT: sd a0, -288(a1) ; LP64-LP64F-LP64D-WITHFP-NEXT: lw a0, 8(s0) +; LP64-LP64F-LP64D-WITHFP-NEXT: sd a5, 40(s0) +; LP64-LP64F-LP64D-WITHFP-NEXT: sd a4, 32(s0) +; LP64-LP64F-LP64D-WITHFP-NEXT: sd a3, 24(s0) +; LP64-LP64F-LP64D-WITHFP-NEXT: sd a2, 16(s0) ; LP64-LP64F-LP64D-WITHFP-NEXT: lui a1, 24414 ; LP64-LP64F-LP64D-WITHFP-NEXT: addiw a1, a1, -1680 ; LP64-LP64F-LP64D-WITHFP-NEXT: add sp, sp, a1 diff --git a/llvm/unittests/Target/RISCV/RISCVInstrInfoTest.cpp b/llvm/unittests/Target/RISCV/RISCVInstrInfoTest.cpp index 135d7dbb426e3c..b4c96a9c2a62ce 100644 --- a/llvm/unittests/Target/RISCV/RISCVInstrInfoTest.cpp +++ b/llvm/unittests/Target/RISCV/RISCVInstrInfoTest.cpp @@ -154,7 +154,6 @@ TEST_P(RISCVInstrInfoTest, GetMemOperandsWithOffsetWidth) { Res = TII->getMemOperandsWithOffsetWidth(*MI, BaseOps, Offset, OffsetIsScalable, Width, TRI); - // TODO: AArch64 can handle this case, and we probably should too. BaseOps.clear(); MMO = MF->getMachineMemOperand(MachinePointerInfo(), MachineMemOperand::MOStore, 4, Align(4)); @@ -165,7 +164,13 @@ TEST_P(RISCVInstrInfoTest, GetMemOperandsWithOffsetWidth) { .addMemOperand(MMO); Res = TII->getMemOperandsWithOffsetWidth(*MI, BaseOps, Offset, OffsetIsScalable, Width, TRI); - EXPECT_FALSE(Res); + ASSERT_TRUE(Res); + ASSERT_EQ(BaseOps.size(), 1u); + ASSERT_TRUE(BaseOps.front()->isFI()); + EXPECT_EQ(BaseOps.front()->getIndex(), 2); + EXPECT_EQ(Offset, 4); + EXPECT_FALSE(OffsetIsScalable); + EXPECT_EQ(Width, 4u); } } // namespace