Index: lib/Target/RISCV/RISCVISelDAGToDAG.cpp =================================================================== --- lib/Target/RISCV/RISCVISelDAGToDAG.cpp +++ lib/Target/RISCV/RISCVISelDAGToDAG.cpp @@ -42,6 +42,8 @@ void Select(SDNode *Node) override; + bool SelectADDRii(SDValue Addr, SDValue &Base, SDValue &Offset); + // Include the pieces autogenerated from the target description. #include "RISCVGenDAGISel.inc" }; @@ -85,6 +87,28 @@ SelectCode(Node); } +bool RISCVDAGToDAGISel::SelectADDRii(SDValue Addr, SDValue &Base, + SDValue &Offset) { + + FrameIndexSDNode *FIN = nullptr; + if ((FIN = dyn_cast(Addr))) { + Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32); + Offset = CurDAG->getTargetConstant(0, SDLoc(Addr), MVT::i32); + return true; + } + if (Addr.getOpcode() == ISD::ADD || Addr.getOpcode() == ISD::OR) { + ConstantSDNode *CN = nullptr; + if ((FIN = dyn_cast(Addr.getOperand(0))) && + (CN = dyn_cast(Addr.getOperand(1)))) { + Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32); + Offset = + CurDAG->getTargetConstant(CN->getSExtValue(), SDLoc(Addr), MVT::i32); + return true; + } + } + return false; +} + // This pass converts a legalized DAG into a RISCV-specific DAG, ready // for instruction scheduling. FunctionPass *llvm::createRISCVISelDag(RISCVTargetMachine &TM) { Index: lib/Target/RISCV/RISCVInstrInfo.cpp =================================================================== --- lib/Target/RISCV/RISCVInstrInfo.cpp +++ lib/Target/RISCV/RISCVInstrInfo.cpp @@ -53,7 +53,7 @@ DL = I->getDebugLoc(); if (RC == &RISCV::GPRRegClass) - BuildMI(MBB, I, DL, get(RISCV::SW)) + BuildMI(MBB, I, DL, get(RISCV::SW_FI)) .addReg(SrcReg, getKillRegState(IsKill)) .addFrameIndex(FI) .addImm(0); @@ -71,7 +71,7 @@ DL = I->getDebugLoc(); if (RC == &RISCV::GPRRegClass) - BuildMI(MBB, I, DL, get(RISCV::LW), DstReg).addFrameIndex(FI).addImm(0); + BuildMI(MBB, I, DL, get(RISCV::LW_FI), DstReg).addFrameIndex(FI).addImm(0); else llvm_unreachable("Can't load this register from stack slot"); } Index: lib/Target/RISCV/RISCVInstrInfo.td =================================================================== --- lib/Target/RISCV/RISCVInstrInfo.td +++ lib/Target/RISCV/RISCVInstrInfo.td @@ -105,12 +105,20 @@ let DecoderMethod = "decodeSImmOperandAndLsl1<21>"; } -// A parameterized register class alternative for i32imm/i64imm from Target.td. +// A parameterized register class alternative to i32imm/i64imm from Target.td. def ixlenimm : Operand; // Standalone (codegen-only) immleaf patterns. def simm32 : ImmLeaf(Imm);}]>; +// Addressing modes. +def ADDRii : ComplexPattern; + +// Address operands. +def MEMii : Operand { + let MIOperandInfo = (ops ixlenimm, ixlenimm); +} + // Extract least significant 12 bits from an immediate value and sign extend // them. def LO12Sext : SDNodeXForm; def : PatGprUimm5; +// Add with a frameindex, used to legalize frameindex copies and necessary to +// keep tblgen happy. +def LEA_FI : Pseudo<(outs GPR:$dst), (ins MEMii:$addr), + [(set GPR:$dst, ADDRii:$addr)]>; + /// Setcc def : PatGprGpr; @@ -413,6 +426,9 @@ defm : LdPat; defm : LdPat; +def LW_FI : Pseudo<(outs GPR:$dst), (ins MEMii:$addr), + [(set GPR:$dst, (load ADDRii:$addr))]>; + /// Stores multiclass StPat { @@ -425,6 +441,9 @@ defm : StPat; defm : StPat; +def SW_FI : Pseudo<(outs), (ins GPR:$src, MEMii:$addr), + [(store GPR:$src, ADDRii:$addr)]>; + /// Other pseudo-instructions // Pessimistically assume the stack pointer will be clobbered Index: lib/Target/RISCV/RISCVRegisterInfo.cpp =================================================================== --- lib/Target/RISCV/RISCVRegisterInfo.cpp +++ lib/Target/RISCV/RISCVRegisterInfo.cpp @@ -57,20 +57,41 @@ void RISCVRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II, int SPAdj, unsigned FIOperandNum, RegScavenger *RS) const { - // TODO: this implementation is a temporary placeholder which does just - // enough to allow other aspects of code generation to be tested - assert(SPAdj == 0 && "Unexpected non-zero SPAdj value"); MachineInstr &MI = *II; MachineFunction &MF = *MI.getParent()->getParent(); + MachineFrameInfo &MFI = MF.getFrameInfo(); const TargetFrameLowering *TFI = MF.getSubtarget().getFrameLowering(); + const TargetInstrInfo *TII = MF.getSubtarget().getInstrInfo(); DebugLoc DL = MI.getDebugLoc(); - unsigned FrameReg = getFrameRegister(MF); int FrameIndex = MI.getOperand(FIOperandNum).getIndex(); - int Offset = TFI->getFrameIndexReference(MF, FrameIndex, FrameReg); - Offset += MI.getOperand(FIOperandNum + 1).getImm(); + unsigned FrameReg; + int Offset = MF.getFrameInfo().getObjectOffset(FrameIndex) + + MI.getOperand(FIOperandNum + 1).getImm(); + + // Callee-saved registers should be referenced relative to the stack + // pointer (positive offset), otherwise use the frame pointer (negative + // offset). + const std::vector &CSI = MFI.getCalleeSavedInfo(); + int MinCSFI = 0; + int MaxCSFI = -1; + + if (CSI.size()) { + MinCSFI = CSI[0].getFrameIdx(); + MaxCSFI = CSI[CSI.size() - 1].getFrameIdx(); + } + + if ((FrameIndex >= MinCSFI && FrameIndex <= MaxCSFI)) { + FrameReg = RISCV::X2; + Offset += MF.getFrameInfo().getStackSize(); + } else { + FrameReg = getFrameRegister(MF); + } + + unsigned Reg = MI.getOperand(0).getReg(); + assert(RISCV::GPRRegClass.contains(Reg) && "Unexpected register operand"); assert(TFI->hasFP(MF) && "eliminateFrameIndex currently requires hasFP"); @@ -80,8 +101,30 @@ "Frame offsets outside of the signed 12-bit range not supported"); } - MI.getOperand(FIOperandNum).ChangeToRegister(FrameReg, false); - MI.getOperand(FIOperandNum + 1).ChangeToImmediate(Offset); + MachineBasicBlock &MBB = *MI.getParent(); + switch (MI.getOpcode()) { + case RISCV::LW_FI: + BuildMI(MBB, II, DL, TII->get(RISCV::LW), Reg) + .addReg(FrameReg) + .addImm(Offset); + break; + case RISCV::SW_FI: + BuildMI(MBB, II, DL, TII->get(RISCV::SW)) + .addReg(Reg, getKillRegState(MI.getOperand(0).isKill())) + .addReg(FrameReg) + .addImm(Offset); + break; + case RISCV::LEA_FI: + BuildMI(MBB, II, DL, TII->get(RISCV::ADDI), Reg) + .addReg(FrameReg) + .addImm(Offset); + break; + default: + llvm_unreachable("Unexpected opcode"); + } + + // Erase old instruction. + MBB.erase(II); return; } Index: test/CodeGen/RISCV/blockaddress.ll =================================================================== --- test/CodeGen/RISCV/blockaddress.ll +++ test/CodeGen/RISCV/blockaddress.ll @@ -7,7 +7,7 @@ define void @test_blockaddress() nounwind { ; RV32I-LABEL: test_blockaddress: ; RV32I: # BB#0: -; RV32I-NEXT: sw ra, 0(s0) +; RV32I-NEXT: sw ra, 0(sp) ; RV32I-NEXT: lui a0, %hi(addr) ; RV32I-NEXT: addi a0, a0, %lo(addr) ; RV32I-NEXT: lui a1, %hi(.Ltmp0) @@ -17,7 +17,7 @@ ; RV32I-NEXT: jalr zero, a0, 0 ; RV32I-NEXT: .Ltmp0: # Block address taken ; RV32I-NEXT: .LBB0_1: # %block -; RV32I-NEXT: lw ra, 0(s0) +; RV32I-NEXT: lw ra, 0(sp) ; RV32I-NEXT: jalr zero, ra, 0 store volatile i8* blockaddress(@test_blockaddress, %block), i8** @addr %val = load volatile i8*, i8** @addr Index: test/CodeGen/RISCV/bswap-ctlz-cttz-ctpop.ll =================================================================== --- test/CodeGen/RISCV/bswap-ctlz-cttz-ctpop.ll +++ test/CodeGen/RISCV/bswap-ctlz-cttz-ctpop.ll @@ -82,7 +82,7 @@ define i8 @test_cttz_i8(i8 %a) nounwind { ; RV32I-LABEL: test_cttz_i8: ; RV32I: # BB#0: -; RV32I-NEXT: sw ra, 12(s0) +; RV32I-NEXT: sw ra, 12(sp) ; RV32I-NEXT: addi a1, a0, 0 ; RV32I-NEXT: addi a0, zero, 8 ; RV32I-NEXT: andi a2, a1, 255 @@ -115,7 +115,7 @@ ; RV32I-NEXT: jalr ra, a2, 0 ; RV32I-NEXT: srli a0, a0, 24 ; RV32I-NEXT: .LBB3_2: # %cond.end -; RV32I-NEXT: lw ra, 12(s0) +; RV32I-NEXT: lw ra, 12(sp) ; RV32I-NEXT: jalr zero, ra, 0 %tmp = call i8 @llvm.cttz.i8(i8 %a, i1 false) ret i8 %tmp @@ -124,7 +124,7 @@ define i16 @test_cttz_i16(i16 %a) nounwind { ; RV32I-LABEL: test_cttz_i16: ; RV32I: # BB#0: -; RV32I-NEXT: sw ra, 12(s0) +; RV32I-NEXT: sw ra, 12(sp) ; RV32I-NEXT: addi a1, a0, 0 ; RV32I-NEXT: addi a0, zero, 16 ; RV32I-NEXT: lui a2, 16 @@ -159,7 +159,7 @@ ; RV32I-NEXT: jalr ra, a2, 0 ; RV32I-NEXT: srli a0, a0, 24 ; RV32I-NEXT: .LBB4_2: # %cond.end -; RV32I-NEXT: lw ra, 12(s0) +; RV32I-NEXT: lw ra, 12(sp) ; RV32I-NEXT: jalr zero, ra, 0 %tmp = call i16 @llvm.cttz.i16(i16 %a, i1 false) ret i16 %tmp @@ -168,7 +168,7 @@ define i32 @test_cttz_i32(i32 %a) nounwind { ; RV32I-LABEL: test_cttz_i32: ; RV32I: # BB#0: -; RV32I-NEXT: sw ra, 12(s0) +; RV32I-NEXT: sw ra, 12(sp) ; RV32I-NEXT: addi a1, a0, 0 ; RV32I-NEXT: addi a0, zero, 32 ; RV32I-NEXT: beq a1, zero, .LBB5_2 @@ -200,7 +200,7 @@ ; RV32I-NEXT: jalr ra, a2, 0 ; RV32I-NEXT: srli a0, a0, 24 ; RV32I-NEXT: .LBB5_2: # %cond.end -; RV32I-NEXT: lw ra, 12(s0) +; RV32I-NEXT: lw ra, 12(sp) ; RV32I-NEXT: jalr zero, ra, 0 %tmp = call i32 @llvm.cttz.i32(i32 %a, i1 false) ret i32 %tmp @@ -209,7 +209,7 @@ define i32 @test_ctlz_i32(i32 %a) nounwind { ; RV32I-LABEL: test_ctlz_i32: ; RV32I: # BB#0: -; RV32I-NEXT: sw ra, 12(s0) +; RV32I-NEXT: sw ra, 12(sp) ; RV32I-NEXT: addi a1, a0, 0 ; RV32I-NEXT: addi a0, zero, 32 ; RV32I-NEXT: beq a1, zero, .LBB6_2 @@ -249,7 +249,7 @@ ; RV32I-NEXT: jalr ra, a2, 0 ; RV32I-NEXT: srli a0, a0, 24 ; RV32I-NEXT: .LBB6_2: # %cond.end -; RV32I-NEXT: lw ra, 12(s0) +; RV32I-NEXT: lw ra, 12(sp) ; RV32I-NEXT: jalr zero, ra, 0 %tmp = call i32 @llvm.ctlz.i32(i32 %a, i1 false) ret i32 %tmp @@ -258,14 +258,14 @@ define i64 @test_cttz_i64(i64 %a) nounwind { ; RV32I-LABEL: test_cttz_i64: ; RV32I: # BB#0: -; RV32I-NEXT: sw ra, 28(s0) -; RV32I-NEXT: sw s1, 24(s0) -; RV32I-NEXT: sw s2, 20(s0) -; RV32I-NEXT: sw s3, 16(s0) -; RV32I-NEXT: sw s4, 12(s0) -; RV32I-NEXT: sw s5, 8(s0) -; RV32I-NEXT: sw s6, 4(s0) -; RV32I-NEXT: sw s7, 0(s0) +; RV32I-NEXT: sw ra, 28(sp) +; RV32I-NEXT: sw s1, 24(sp) +; RV32I-NEXT: sw s2, 20(sp) +; RV32I-NEXT: sw s3, 16(sp) +; RV32I-NEXT: sw s4, 12(sp) +; RV32I-NEXT: sw s5, 8(sp) +; RV32I-NEXT: sw s6, 4(sp) +; RV32I-NEXT: sw s7, 0(sp) ; RV32I-NEXT: addi s1, a1, 0 ; RV32I-NEXT: addi s2, a0, 0 ; RV32I-NEXT: addi a0, s2, -1 @@ -317,14 +317,14 @@ ; RV32I-NEXT: .LBB7_2: ; RV32I-NEXT: addi a0, s1, 0 ; RV32I-NEXT: addi a1, zero, 0 -; RV32I-NEXT: lw s7, 0(s0) -; RV32I-NEXT: lw s6, 4(s0) -; RV32I-NEXT: lw s5, 8(s0) -; RV32I-NEXT: lw s4, 12(s0) -; RV32I-NEXT: lw s3, 16(s0) -; RV32I-NEXT: lw s2, 20(s0) -; RV32I-NEXT: lw s1, 24(s0) -; RV32I-NEXT: lw ra, 28(s0) +; RV32I-NEXT: lw s7, 0(sp) +; RV32I-NEXT: lw s6, 4(sp) +; RV32I-NEXT: lw s5, 8(sp) +; RV32I-NEXT: lw s4, 12(sp) +; RV32I-NEXT: lw s3, 16(sp) +; RV32I-NEXT: lw s2, 20(sp) +; RV32I-NEXT: lw s1, 24(sp) +; RV32I-NEXT: lw ra, 28(sp) ; RV32I-NEXT: jalr zero, ra, 0 %tmp = call i64 @llvm.cttz.i64(i64 %a, i1 false) ret i64 %tmp @@ -333,7 +333,7 @@ define i8 @test_cttz_i8_zero_undef(i8 %a) nounwind { ; RV32I-LABEL: test_cttz_i8_zero_undef: ; RV32I: # BB#0: -; RV32I-NEXT: sw ra, 12(s0) +; RV32I-NEXT: sw ra, 12(sp) ; RV32I-NEXT: addi a1, a0, -1 ; RV32I-NEXT: xori a0, a0, -1 ; RV32I-NEXT: and a0, a0, a1 @@ -359,7 +359,7 @@ ; RV32I-NEXT: addi a2, a2, %lo(__mulsi3) ; RV32I-NEXT: jalr ra, a2, 0 ; RV32I-NEXT: srli a0, a0, 24 -; RV32I-NEXT: lw ra, 12(s0) +; RV32I-NEXT: lw ra, 12(sp) ; RV32I-NEXT: jalr zero, ra, 0 %tmp = call i8 @llvm.cttz.i8(i8 %a, i1 true) ret i8 %tmp @@ -368,7 +368,7 @@ define i16 @test_cttz_i16_zero_undef(i16 %a) nounwind { ; RV32I-LABEL: test_cttz_i16_zero_undef: ; RV32I: # BB#0: -; RV32I-NEXT: sw ra, 12(s0) +; RV32I-NEXT: sw ra, 12(sp) ; RV32I-NEXT: addi a1, a0, -1 ; RV32I-NEXT: xori a0, a0, -1 ; RV32I-NEXT: and a0, a0, a1 @@ -394,7 +394,7 @@ ; RV32I-NEXT: addi a2, a2, %lo(__mulsi3) ; RV32I-NEXT: jalr ra, a2, 0 ; RV32I-NEXT: srli a0, a0, 24 -; RV32I-NEXT: lw ra, 12(s0) +; RV32I-NEXT: lw ra, 12(sp) ; RV32I-NEXT: jalr zero, ra, 0 %tmp = call i16 @llvm.cttz.i16(i16 %a, i1 true) ret i16 %tmp @@ -403,7 +403,7 @@ define i32 @test_cttz_i32_zero_undef(i32 %a) nounwind { ; RV32I-LABEL: test_cttz_i32_zero_undef: ; RV32I: # BB#0: -; RV32I-NEXT: sw ra, 12(s0) +; RV32I-NEXT: sw ra, 12(sp) ; RV32I-NEXT: addi a1, a0, -1 ; RV32I-NEXT: xori a0, a0, -1 ; RV32I-NEXT: and a0, a0, a1 @@ -429,7 +429,7 @@ ; RV32I-NEXT: addi a2, a2, %lo(__mulsi3) ; RV32I-NEXT: jalr ra, a2, 0 ; RV32I-NEXT: srli a0, a0, 24 -; RV32I-NEXT: lw ra, 12(s0) +; RV32I-NEXT: lw ra, 12(sp) ; RV32I-NEXT: jalr zero, ra, 0 %tmp = call i32 @llvm.cttz.i32(i32 %a, i1 true) ret i32 %tmp @@ -438,14 +438,14 @@ define i64 @test_cttz_i64_zero_undef(i64 %a) nounwind { ; RV32I-LABEL: test_cttz_i64_zero_undef: ; RV32I: # BB#0: -; RV32I-NEXT: sw ra, 28(s0) -; RV32I-NEXT: sw s1, 24(s0) -; RV32I-NEXT: sw s2, 20(s0) -; RV32I-NEXT: sw s3, 16(s0) -; RV32I-NEXT: sw s4, 12(s0) -; RV32I-NEXT: sw s5, 8(s0) -; RV32I-NEXT: sw s6, 4(s0) -; RV32I-NEXT: sw s7, 0(s0) +; RV32I-NEXT: sw ra, 28(sp) +; RV32I-NEXT: sw s1, 24(sp) +; RV32I-NEXT: sw s2, 20(sp) +; RV32I-NEXT: sw s3, 16(sp) +; RV32I-NEXT: sw s4, 12(sp) +; RV32I-NEXT: sw s5, 8(sp) +; RV32I-NEXT: sw s6, 4(sp) +; RV32I-NEXT: sw s7, 0(sp) ; RV32I-NEXT: addi s1, a1, 0 ; RV32I-NEXT: addi s2, a0, 0 ; RV32I-NEXT: addi a0, s2, -1 @@ -497,14 +497,14 @@ ; RV32I-NEXT: .LBB11_2: ; RV32I-NEXT: addi a0, s1, 0 ; RV32I-NEXT: addi a1, zero, 0 -; RV32I-NEXT: lw s7, 0(s0) -; RV32I-NEXT: lw s6, 4(s0) -; RV32I-NEXT: lw s5, 8(s0) -; RV32I-NEXT: lw s4, 12(s0) -; RV32I-NEXT: lw s3, 16(s0) -; RV32I-NEXT: lw s2, 20(s0) -; RV32I-NEXT: lw s1, 24(s0) -; RV32I-NEXT: lw ra, 28(s0) +; RV32I-NEXT: lw s7, 0(sp) +; RV32I-NEXT: lw s6, 4(sp) +; RV32I-NEXT: lw s5, 8(sp) +; RV32I-NEXT: lw s4, 12(sp) +; RV32I-NEXT: lw s3, 16(sp) +; RV32I-NEXT: lw s2, 20(sp) +; RV32I-NEXT: lw s1, 24(sp) +; RV32I-NEXT: lw ra, 28(sp) ; RV32I-NEXT: jalr zero, ra, 0 %tmp = call i64 @llvm.cttz.i64(i64 %a, i1 true) ret i64 %tmp @@ -513,7 +513,7 @@ define i32 @test_ctpop_i32(i32 %a) nounwind { ; RV32I-LABEL: test_ctpop_i32: ; RV32I: # BB#0: -; RV32I-NEXT: sw ra, 12(s0) +; RV32I-NEXT: sw ra, 12(sp) ; RV32I-NEXT: lui a1, 349525 ; RV32I-NEXT: addi a1, a1, 1365 ; RV32I-NEXT: srli a2, a0, 1 @@ -536,7 +536,7 @@ ; RV32I-NEXT: addi a2, a2, %lo(__mulsi3) ; RV32I-NEXT: jalr ra, a2, 0 ; RV32I-NEXT: srli a0, a0, 24 -; RV32I-NEXT: lw ra, 12(s0) +; RV32I-NEXT: lw ra, 12(sp) ; RV32I-NEXT: jalr zero, ra, 0 %1 = call i32 @llvm.ctpop.i32(i32 %a) ret i32 %1 Index: test/CodeGen/RISCV/calls.ll =================================================================== --- test/CodeGen/RISCV/calls.ll +++ test/CodeGen/RISCV/calls.ll @@ -7,11 +7,11 @@ define i32 @test_call_external(i32 %a) nounwind { ; RV32I-LABEL: test_call_external: ; RV32I: # BB#0: -; RV32I-NEXT: sw ra, 12(s0) +; RV32I-NEXT: sw ra, 12(sp) ; RV32I-NEXT: lui a1, %hi(external_function) ; RV32I-NEXT: addi a1, a1, %lo(external_function) ; RV32I-NEXT: jalr ra, a1, 0 -; RV32I-NEXT: lw ra, 12(s0) +; RV32I-NEXT: lw ra, 12(sp) ; RV32I-NEXT: jalr zero, ra, 0 %1 = call i32 @external_function(i32 %a) ret i32 %1 @@ -29,11 +29,11 @@ define i32 @test_call_defined(i32 %a) nounwind { ; RV32I-LABEL: test_call_defined: ; RV32I: # BB#0: -; RV32I-NEXT: sw ra, 12(s0) +; RV32I-NEXT: sw ra, 12(sp) ; RV32I-NEXT: lui a1, %hi(defined_function) ; RV32I-NEXT: addi a1, a1, %lo(defined_function) ; RV32I-NEXT: jalr ra, a1, 0 -; RV32I-NEXT: lw ra, 12(s0) +; RV32I-NEXT: lw ra, 12(sp) ; RV32I-NEXT: jalr zero, ra, 0 %1 = call i32 @defined_function(i32 %a) nounwind ret i32 %1 @@ -42,11 +42,11 @@ define i32 @test_call_indirect(i32 (i32)* %a, i32 %b) nounwind { ; RV32I-LABEL: test_call_indirect: ; RV32I: # BB#0: -; RV32I-NEXT: sw ra, 12(s0) +; RV32I-NEXT: sw ra, 12(sp) ; RV32I-NEXT: addi a2, a0, 0 ; RV32I-NEXT: addi a0, a1, 0 ; RV32I-NEXT: jalr ra, a2, 0 -; RV32I-NEXT: lw ra, 12(s0) +; RV32I-NEXT: lw ra, 12(sp) ; RV32I-NEXT: jalr zero, ra, 0 %1 = call i32 %a(i32 %b) ret i32 %1 @@ -67,16 +67,16 @@ define i32 @test_call_fastcc(i32 %a, i32 %b) nounwind { ; RV32I-LABEL: test_call_fastcc: ; RV32I: # BB#0: -; RV32I-NEXT: sw ra, 12(s0) -; RV32I-NEXT: sw s1, 8(s0) +; RV32I-NEXT: sw ra, 12(sp) +; RV32I-NEXT: sw s1, 8(sp) ; RV32I-NEXT: addi s1, a0, 0 ; RV32I-NEXT: lui a0, %hi(fastcc_function) ; RV32I-NEXT: addi a2, a0, %lo(fastcc_function) ; RV32I-NEXT: addi a0, s1, 0 ; RV32I-NEXT: jalr ra, a2, 0 ; RV32I-NEXT: addi a0, s1, 0 -; RV32I-NEXT: lw s1, 8(s0) -; RV32I-NEXT: lw ra, 12(s0) +; RV32I-NEXT: lw s1, 8(sp) +; RV32I-NEXT: lw ra, 12(sp) ; RV32I-NEXT: jalr zero, ra, 0 %1 = call fastcc i32 @fastcc_function(i32 %a, i32 %b) ret i32 %a Index: test/CodeGen/RISCV/div.ll =================================================================== --- test/CodeGen/RISCV/div.ll +++ test/CodeGen/RISCV/div.ll @@ -5,11 +5,11 @@ define i32 @udiv(i32 %a, i32 %b) { ; RV32I-LABEL: udiv: ; RV32I: # BB#0: -; RV32I-NEXT: sw ra, 12(s0) +; RV32I-NEXT: sw ra, 12(sp) ; RV32I-NEXT: lui a2, %hi(__udivsi3) ; RV32I-NEXT: addi a2, a2, %lo(__udivsi3) ; RV32I-NEXT: jalr ra, a2, 0 -; RV32I-NEXT: lw ra, 12(s0) +; RV32I-NEXT: lw ra, 12(sp) ; RV32I-NEXT: jalr zero, ra, 0 %1 = udiv i32 %a, %b ret i32 %1 @@ -18,12 +18,12 @@ define i32 @udiv_constant(i32 %a) { ; RV32I-LABEL: udiv_constant: ; RV32I: # BB#0: -; RV32I-NEXT: sw ra, 12(s0) +; RV32I-NEXT: sw ra, 12(sp) ; RV32I-NEXT: lui a1, %hi(__udivsi3) ; RV32I-NEXT: addi a2, a1, %lo(__udivsi3) ; RV32I-NEXT: addi a1, zero, 5 ; RV32I-NEXT: jalr ra, a2, 0 -; RV32I-NEXT: lw ra, 12(s0) +; RV32I-NEXT: lw ra, 12(sp) ; RV32I-NEXT: jalr zero, ra, 0 %1 = udiv i32 %a, 5 ret i32 %1 @@ -41,11 +41,11 @@ define i64 @udiv64(i64 %a, i64 %b) { ; RV32I-LABEL: udiv64: ; RV32I: # BB#0: -; RV32I-NEXT: sw ra, 12(s0) +; RV32I-NEXT: sw ra, 12(sp) ; RV32I-NEXT: lui a4, %hi(__udivdi3) ; RV32I-NEXT: addi a4, a4, %lo(__udivdi3) ; RV32I-NEXT: jalr ra, a4, 0 -; RV32I-NEXT: lw ra, 12(s0) +; RV32I-NEXT: lw ra, 12(sp) ; RV32I-NEXT: jalr zero, ra, 0 %1 = udiv i64 %a, %b ret i64 %1 @@ -54,13 +54,13 @@ define i64 @udiv64_constant(i64 %a) { ; RV32I-LABEL: udiv64_constant: ; RV32I: # BB#0: -; RV32I-NEXT: sw ra, 12(s0) +; RV32I-NEXT: sw ra, 12(sp) ; RV32I-NEXT: lui a2, %hi(__udivdi3) ; RV32I-NEXT: addi a4, a2, %lo(__udivdi3) ; RV32I-NEXT: addi a2, zero, 5 ; RV32I-NEXT: addi a3, zero, 0 ; RV32I-NEXT: jalr ra, a4, 0 -; RV32I-NEXT: lw ra, 12(s0) +; RV32I-NEXT: lw ra, 12(sp) ; RV32I-NEXT: jalr zero, ra, 0 %1 = udiv i64 %a, 5 ret i64 %1 @@ -69,11 +69,11 @@ define i32 @sdiv(i32 %a, i32 %b) { ; RV32I-LABEL: sdiv: ; RV32I: # BB#0: -; RV32I-NEXT: sw ra, 12(s0) +; RV32I-NEXT: sw ra, 12(sp) ; RV32I-NEXT: lui a2, %hi(__divsi3) ; RV32I-NEXT: addi a2, a2, %lo(__divsi3) ; RV32I-NEXT: jalr ra, a2, 0 -; RV32I-NEXT: lw ra, 12(s0) +; RV32I-NEXT: lw ra, 12(sp) ; RV32I-NEXT: jalr zero, ra, 0 %1 = sdiv i32 %a, %b ret i32 %1 @@ -82,12 +82,12 @@ define i32 @sdiv_constant(i32 %a) { ; RV32I-LABEL: sdiv_constant: ; RV32I: # BB#0: -; RV32I-NEXT: sw ra, 12(s0) +; RV32I-NEXT: sw ra, 12(sp) ; RV32I-NEXT: lui a1, %hi(__divsi3) ; RV32I-NEXT: addi a2, a1, %lo(__divsi3) ; RV32I-NEXT: addi a1, zero, 5 ; RV32I-NEXT: jalr ra, a2, 0 -; RV32I-NEXT: lw ra, 12(s0) +; RV32I-NEXT: lw ra, 12(sp) ; RV32I-NEXT: jalr zero, ra, 0 %1 = sdiv i32 %a, 5 ret i32 %1 @@ -108,11 +108,11 @@ define i64 @sdiv64(i64 %a, i64 %b) { ; RV32I-LABEL: sdiv64: ; RV32I: # BB#0: -; RV32I-NEXT: sw ra, 12(s0) +; RV32I-NEXT: sw ra, 12(sp) ; RV32I-NEXT: lui a4, %hi(__divdi3) ; RV32I-NEXT: addi a4, a4, %lo(__divdi3) ; RV32I-NEXT: jalr ra, a4, 0 -; RV32I-NEXT: lw ra, 12(s0) +; RV32I-NEXT: lw ra, 12(sp) ; RV32I-NEXT: jalr zero, ra, 0 %1 = sdiv i64 %a, %b ret i64 %1 @@ -121,13 +121,13 @@ define i64 @sdiv64_constant(i64 %a) { ; RV32I-LABEL: sdiv64_constant: ; RV32I: # BB#0: -; RV32I-NEXT: sw ra, 12(s0) +; RV32I-NEXT: sw ra, 12(sp) ; RV32I-NEXT: lui a2, %hi(__divdi3) ; RV32I-NEXT: addi a4, a2, %lo(__divdi3) ; RV32I-NEXT: addi a2, zero, 5 ; RV32I-NEXT: addi a3, zero, 0 ; RV32I-NEXT: jalr ra, a4, 0 -; RV32I-NEXT: lw ra, 12(s0) +; RV32I-NEXT: lw ra, 12(sp) ; RV32I-NEXT: jalr zero, ra, 0 %1 = sdiv i64 %a, 5 ret i64 %1 Index: test/CodeGen/RISCV/frame.ll =================================================================== --- /dev/null +++ test/CodeGen/RISCV/frame.ll @@ -0,0 +1,37 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +; RUN: llc -mtriple=riscv32 -verify-machineinstrs < %s \ +; RUN: | FileCheck -check-prefix=RV32I %s + +%struct.key_t = type { i32, [16 x i8] } + +; FIXME: prologue and epilogue insertion must be implemented to complete this +; test + +define i32 @test() nounwind { +; RV32I-LABEL: test: +; RV32I: # BB#0: +; RV32I-NEXT: sw ra, 28(sp) +; RV32I-NEXT: sw zero, -8(s0) +; RV32I-NEXT: sw zero, -12(s0) +; RV32I-NEXT: sw zero, -16(s0) +; RV32I-NEXT: sw zero, -20(s0) +; RV32I-NEXT: sw zero, -24(s0) +; RV32I-NEXT: addi a0, s0, -24 +; RV32I-NEXT: ori a0, a0, 4 +; RV32I-NEXT: lui a1, %hi(test1) +; RV32I-NEXT: addi a1, a1, %lo(test1) +; RV32I-NEXT: jalr ra, a1, 0 +; RV32I-NEXT: addi a0, zero, 0 +; RV32I-NEXT: lw ra, 28(sp) +; RV32I-NEXT: jalr zero, ra, 0 + %key = alloca %struct.key_t, align 4 + %1 = bitcast %struct.key_t* %key to i8* + call void @llvm.memset.p0i8.i64(i8* %1, i8 0, i64 20, i32 4, i1 false) + %2 = getelementptr inbounds %struct.key_t, %struct.key_t* %key, i64 0, i32 1, i64 0 + call void @test1(i8* %2) #3 + ret i32 0 +} + +declare void @llvm.memset.p0i8.i64(i8* nocapture, i8, i64, i32, i1) + +declare void @test1(i8*) Index: test/CodeGen/RISCV/indirectbr.ll =================================================================== --- test/CodeGen/RISCV/indirectbr.ll +++ test/CodeGen/RISCV/indirectbr.ll @@ -5,11 +5,11 @@ define i32 @indirectbr(i8* %target) nounwind { ; RV32I-LABEL: indirectbr: ; RV32I: # BB#0: -; RV32I-NEXT: sw ra, 0(s0) +; RV32I-NEXT: sw ra, 0(sp) ; RV32I-NEXT: jalr zero, a0, 0 ; RV32I-NEXT: .LBB0_1: # %ret ; RV32I-NEXT: addi a0, zero, 0 -; RV32I-NEXT: lw ra, 0(s0) +; RV32I-NEXT: lw ra, 0(sp) ; RV32I-NEXT: jalr zero, ra, 0 indirectbr i8* %target, [label %test_label] test_label: @@ -21,11 +21,11 @@ define i32 @indirectbr_with_offset(i8* %a) nounwind { ; RV32I-LABEL: indirectbr_with_offset: ; RV32I: # BB#0: -; RV32I-NEXT: sw ra, 0(s0) +; RV32I-NEXT: sw ra, 0(sp) ; RV32I-NEXT: jalr zero, a0, 1380 ; RV32I-NEXT: .LBB1_1: # %ret ; RV32I-NEXT: addi a0, zero, 0 -; RV32I-NEXT: lw ra, 0(s0) +; RV32I-NEXT: lw ra, 0(sp) ; RV32I-NEXT: jalr zero, ra, 0 %target = getelementptr inbounds i8, i8* %a, i32 1380 indirectbr i8* %target, [label %test_label] Index: test/CodeGen/RISCV/mul.ll =================================================================== --- test/CodeGen/RISCV/mul.ll +++ test/CodeGen/RISCV/mul.ll @@ -5,12 +5,12 @@ define i32 @square(i32 %a) { ; RV32I-LABEL: square: ; RV32I: # BB#0: -; RV32I-NEXT: sw ra, 12(s0) +; RV32I-NEXT: sw ra, 12(sp) ; RV32I-NEXT: lui a1, %hi(__mulsi3) ; RV32I-NEXT: addi a2, a1, %lo(__mulsi3) ; RV32I-NEXT: addi a1, a0, 0 ; RV32I-NEXT: jalr ra, a2, 0 -; RV32I-NEXT: lw ra, 12(s0) +; RV32I-NEXT: lw ra, 12(sp) ; RV32I-NEXT: jalr zero, ra, 0 %1 = mul i32 %a, %a ret i32 %1 @@ -19,11 +19,11 @@ define i32 @mul(i32 %a, i32 %b) { ; RV32I-LABEL: mul: ; RV32I: # BB#0: -; RV32I-NEXT: sw ra, 12(s0) +; RV32I-NEXT: sw ra, 12(sp) ; RV32I-NEXT: lui a2, %hi(__mulsi3) ; RV32I-NEXT: addi a2, a2, %lo(__mulsi3) ; RV32I-NEXT: jalr ra, a2, 0 -; RV32I-NEXT: lw ra, 12(s0) +; RV32I-NEXT: lw ra, 12(sp) ; RV32I-NEXT: jalr zero, ra, 0 %1 = mul i32 %a, %b ret i32 %1 @@ -32,12 +32,12 @@ define i32 @mul_constant(i32 %a) { ; RV32I-LABEL: mul_constant: ; RV32I: # BB#0: -; RV32I-NEXT: sw ra, 12(s0) +; RV32I-NEXT: sw ra, 12(sp) ; RV32I-NEXT: lui a1, %hi(__mulsi3) ; RV32I-NEXT: addi a2, a1, %lo(__mulsi3) ; RV32I-NEXT: addi a1, zero, 5 ; RV32I-NEXT: jalr ra, a2, 0 -; RV32I-NEXT: lw ra, 12(s0) +; RV32I-NEXT: lw ra, 12(sp) ; RV32I-NEXT: jalr zero, ra, 0 %1 = mul i32 %a, 5 ret i32 %1 @@ -55,11 +55,11 @@ define i64 @mul64(i64 %a, i64 %b) { ; RV32I-LABEL: mul64: ; RV32I: # BB#0: -; RV32I-NEXT: sw ra, 12(s0) +; RV32I-NEXT: sw ra, 12(sp) ; RV32I-NEXT: lui a4, %hi(__muldi3) ; RV32I-NEXT: addi a4, a4, %lo(__muldi3) ; RV32I-NEXT: jalr ra, a4, 0 -; RV32I-NEXT: lw ra, 12(s0) +; RV32I-NEXT: lw ra, 12(sp) ; RV32I-NEXT: jalr zero, ra, 0 %1 = mul i64 %a, %b ret i64 %1 @@ -68,13 +68,13 @@ define i64 @mul64_constant(i64 %a) { ; RV32I-LABEL: mul64_constant: ; RV32I: # BB#0: -; RV32I-NEXT: sw ra, 12(s0) +; RV32I-NEXT: sw ra, 12(sp) ; RV32I-NEXT: lui a2, %hi(__muldi3) ; RV32I-NEXT: addi a4, a2, %lo(__muldi3) ; RV32I-NEXT: addi a2, zero, 5 ; RV32I-NEXT: addi a3, zero, 0 ; RV32I-NEXT: jalr ra, a4, 0 -; RV32I-NEXT: lw ra, 12(s0) +; RV32I-NEXT: lw ra, 12(sp) ; RV32I-NEXT: jalr zero, ra, 0 %1 = mul i64 %a, 5 ret i64 %1 Index: test/CodeGen/RISCV/rem.ll =================================================================== --- test/CodeGen/RISCV/rem.ll +++ test/CodeGen/RISCV/rem.ll @@ -5,11 +5,11 @@ define i32 @urem(i32 %a, i32 %b) nounwind { ; RV32I-LABEL: urem: ; RV32I: # BB#0: -; RV32I-NEXT: sw ra, 12(s0) +; RV32I-NEXT: sw ra, 12(sp) ; RV32I-NEXT: lui a2, %hi(__umodsi3) ; RV32I-NEXT: addi a2, a2, %lo(__umodsi3) ; RV32I-NEXT: jalr ra, a2, 0 -; RV32I-NEXT: lw ra, 12(s0) +; RV32I-NEXT: lw ra, 12(sp) ; RV32I-NEXT: jalr zero, ra, 0 %1 = urem i32 %a, %b ret i32 %1 @@ -18,11 +18,11 @@ define i32 @srem(i32 %a, i32 %b) nounwind { ; RV32I-LABEL: srem: ; RV32I: # BB#0: -; RV32I-NEXT: sw ra, 12(s0) +; RV32I-NEXT: sw ra, 12(sp) ; RV32I-NEXT: lui a2, %hi(__modsi3) ; RV32I-NEXT: addi a2, a2, %lo(__modsi3) ; RV32I-NEXT: jalr ra, a2, 0 -; RV32I-NEXT: lw ra, 12(s0) +; RV32I-NEXT: lw ra, 12(sp) ; RV32I-NEXT: jalr zero, ra, 0 %1 = srem i32 %a, %b ret i32 %1 Index: test/CodeGen/RISCV/shifts.ll =================================================================== --- test/CodeGen/RISCV/shifts.ll +++ test/CodeGen/RISCV/shifts.ll @@ -8,11 +8,11 @@ define i64 @lshr64(i64 %a, i64 %b) nounwind { ; RV32I-LABEL: lshr64: ; RV32I: # BB#0: -; RV32I-NEXT: sw ra, 12(s0) +; RV32I-NEXT: sw ra, 12(sp) ; RV32I-NEXT: lui a3, %hi(__lshrdi3) ; RV32I-NEXT: addi a3, a3, %lo(__lshrdi3) ; RV32I-NEXT: jalr ra, a3, 0 -; RV32I-NEXT: lw ra, 12(s0) +; RV32I-NEXT: lw ra, 12(sp) ; RV32I-NEXT: jalr zero, ra, 0 %1 = lshr i64 %a, %b ret i64 %1 @@ -21,11 +21,11 @@ define i64 @ashr64(i64 %a, i64 %b) nounwind { ; RV32I-LABEL: ashr64: ; RV32I: # BB#0: -; RV32I-NEXT: sw ra, 12(s0) +; RV32I-NEXT: sw ra, 12(sp) ; RV32I-NEXT: lui a3, %hi(__ashrdi3) ; RV32I-NEXT: addi a3, a3, %lo(__ashrdi3) ; RV32I-NEXT: jalr ra, a3, 0 -; RV32I-NEXT: lw ra, 12(s0) +; RV32I-NEXT: lw ra, 12(sp) ; RV32I-NEXT: jalr zero, ra, 0 %1 = ashr i64 %a, %b ret i64 %1 @@ -34,11 +34,11 @@ define i64 @shl64(i64 %a, i64 %b) nounwind { ; RV32I-LABEL: shl64: ; RV32I: # BB#0: -; RV32I-NEXT: sw ra, 12(s0) +; RV32I-NEXT: sw ra, 12(sp) ; RV32I-NEXT: lui a3, %hi(__ashldi3) ; RV32I-NEXT: addi a3, a3, %lo(__ashldi3) ; RV32I-NEXT: jalr ra, a3, 0 -; RV32I-NEXT: lw ra, 12(s0) +; RV32I-NEXT: lw ra, 12(sp) ; RV32I-NEXT: jalr zero, ra, 0 %1 = shl i64 %a, %b ret i64 %1