diff --git a/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp b/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp index 0f948b22759fe..ddba47b1975c7 100644 --- a/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp +++ b/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp @@ -2942,8 +2942,8 @@ bool RISCVDAGToDAGISel::SelectAddrRegImm(SDValue Addr, SDValue &Base, /// Similar to SelectAddrRegImm, except that the offset is restricted to uimm9. bool RISCVDAGToDAGISel::SelectAddrRegImm9(SDValue Addr, SDValue &Base, SDValue &Offset) { - // FIXME: Support FrameIndex. Need to teach eliminateFrameIndex that only - // a 9-bit immediate can be folded. + if (SelectAddrFrameIndex(Addr, Base, Offset)) + return true; SDLoc DL(Addr); MVT VT = Addr.getSimpleValueType(); @@ -2953,8 +2953,8 @@ bool RISCVDAGToDAGISel::SelectAddrRegImm9(SDValue Addr, SDValue &Base, if (isUInt<9>(CVal)) { Base = Addr.getOperand(0); - // FIXME: Support FrameIndex. Need to teach eliminateFrameIndex that only - // a 9-bit immediate can be folded. + if (auto *FIN = dyn_cast(Base)) + Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), VT); Offset = CurDAG->getSignedTargetConstant(CVal, DL, VT); return true; } diff --git a/llvm/lib/Target/RISCV/RISCVRegisterInfo.cpp b/llvm/lib/Target/RISCV/RISCVRegisterInfo.cpp index 540412366026b..0c51b08071949 100644 --- a/llvm/lib/Target/RISCV/RISCVRegisterInfo.cpp +++ b/llvm/lib/Target/RISCV/RISCVRegisterInfo.cpp @@ -573,6 +573,8 @@ bool RISCVRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II, int64_t Val = Offset.getFixed(); int64_t Lo12 = SignExtend64<12>(Val); unsigned Opc = MI.getOpcode(); + auto &Subtarget = MF.getSubtarget(); + if (Opc == RISCV::ADDI && !isInt<12>(Val)) { // We chose to emit the canonical immediate sequence rather than folding // the offset into the using add under the theory that doing so doesn't @@ -585,6 +587,9 @@ bool RISCVRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II, (Lo12 & 0b11111) != 0) { // Prefetch instructions require the offset to be 32 byte aligned. MI.getOperand(FIOperandNum + 1).ChangeToImmediate(0); + } else if (Opc == RISCV::MIPS_PREFETCH && !isUInt<9>(Val)) { + // MIPS Prefetch instructions require the offset to be 9 bits encoded. + MI.getOperand(FIOperandNum + 1).ChangeToImmediate(0); } else if ((Opc == RISCV::PseudoRV32ZdinxLD || Opc == RISCV::PseudoRV32ZdinxSD) && Lo12 >= 2044) { diff --git a/llvm/test/CodeGen/RISCV/xmips-cbop.ll b/llvm/test/CodeGen/RISCV/xmips-cbop.ll index cbbd1de13192c..0d5defc833763 100644 --- a/llvm/test/CodeGen/RISCV/xmips-cbop.ll +++ b/llvm/test/CodeGen/RISCV/xmips-cbop.ll @@ -1,7 +1,7 @@ ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5 -; RUN: llc -mtriple=riscv32 -mattr=+xmipscbop -mattr=+m -verify-machineinstrs < %s \ +; RUN: llc -mtriple=riscv32 -mattr=+xmipscbop -verify-machineinstrs < %s \ ; RUN: | FileCheck %s -check-prefix=RV32XMIPSPREFETCH -; RUN: llc -mtriple=riscv64 -mattr=+xmipscbop -mattr=+m -verify-machineinstrs < %s \ +; RUN: llc -mtriple=riscv64 -mattr=+xmipscbop -verify-machineinstrs < %s \ ; RUN: | FileCheck %s -check-prefix=RV64XMIPSPREFETCH define void @prefetch_data_read(ptr noundef %ptr) nounwind { @@ -49,3 +49,54 @@ define void @prefetch_inst_read(ptr noundef %ptr) nounwind { tail call void @llvm.prefetch.p0(ptr nonnull %arrayidx, i32 0, i32 0, i32 0) ret void } + +define void @prefetch_frameindex_test_neg() nounwind { +; RV32XMIPSPREFETCH-LABEL: prefetch_frameindex_test_neg: +; RV32XMIPSPREFETCH: # %bb.0: +; RV32XMIPSPREFETCH-NEXT: lui a0, 1 +; RV32XMIPSPREFETCH-NEXT: addi a0, a0, 16 +; RV32XMIPSPREFETCH-NEXT: sub sp, sp, a0 +; RV32XMIPSPREFETCH-NEXT: addi a0, sp, 524 +; RV32XMIPSPREFETCH-NEXT: mips.pref 8, 0(a0) +; RV32XMIPSPREFETCH-NEXT: lui a0, 1 +; RV32XMIPSPREFETCH-NEXT: addi a0, a0, 16 +; RV32XMIPSPREFETCH-NEXT: add sp, sp, a0 +; RV32XMIPSPREFETCH-NEXT: ret +; +; RV64XMIPSPREFETCH-LABEL: prefetch_frameindex_test_neg: +; RV64XMIPSPREFETCH: # %bb.0: +; RV64XMIPSPREFETCH-NEXT: lui a0, 1 +; RV64XMIPSPREFETCH-NEXT: addi a0, a0, 16 +; RV64XMIPSPREFETCH-NEXT: sub sp, sp, a0 +; RV64XMIPSPREFETCH-NEXT: addi a0, sp, 524 +; RV64XMIPSPREFETCH-NEXT: mips.pref 8, 0(a0) +; RV64XMIPSPREFETCH-NEXT: lui a0, 1 +; RV64XMIPSPREFETCH-NEXT: addi a0, a0, 16 +; RV64XMIPSPREFETCH-NEXT: add sp, sp, a0 +; RV64XMIPSPREFETCH-NEXT: ret + %data = alloca [1024 x i32], align 4 + %ptr = getelementptr [1024 x i32], ptr %data, i32 0, i32 127 + call void @llvm.prefetch(ptr %ptr, i32 0, i32 0, i32 1) + ret void +} + +define void @prefetch_frameindex_test() nounwind { +; RV32XMIPSPREFETCH-LABEL: prefetch_frameindex_test: +; RV32XMIPSPREFETCH: # %bb.0: +; RV32XMIPSPREFETCH-NEXT: addi sp, sp, -512 +; RV32XMIPSPREFETCH-NEXT: mips.pref 8, 32(sp) +; RV32XMIPSPREFETCH-NEXT: addi sp, sp, 512 +; RV32XMIPSPREFETCH-NEXT: ret +; +; RV64XMIPSPREFETCH-LABEL: prefetch_frameindex_test: +; RV64XMIPSPREFETCH: # %bb.0: +; RV64XMIPSPREFETCH-NEXT: addi sp, sp, -512 +; RV64XMIPSPREFETCH-NEXT: mips.pref 8, 32(sp) +; RV64XMIPSPREFETCH-NEXT: addi sp, sp, 512 +; RV64XMIPSPREFETCH-NEXT: ret + %data = alloca [128 x i32], align 4 + %base = bitcast ptr %data to ptr + %ptr = getelementptr [128 x i32], ptr %base, i32 0, i32 8 + call void @llvm.prefetch(ptr %ptr, i32 0, i32 0, i32 1) + ret void +}