Index: lib/Target/RISCV/RISCVFrameLowering.cpp =================================================================== --- lib/Target/RISCV/RISCVFrameLowering.cpp +++ lib/Target/RISCV/RISCVFrameLowering.cpp @@ -63,7 +63,6 @@ const DebugLoc &DL, Register DestReg, Register SrcReg, int64_t Val, MachineInstr::MIFlag Flag) const { - MachineRegisterInfo &MRI = MBB.getParent()->getRegInfo(); const RISCVInstrInfo *TII = STI.getInstrInfo(); if (DestReg == SrcReg && Val == 0) @@ -74,7 +73,7 @@ .addReg(SrcReg) .addImm(Val) .setMIFlag(Flag); - } else if (isInt<32>(Val)) { + } else { unsigned Opc = RISCV::ADD; bool isSub = Val < 0; if (isSub) { @@ -82,14 +81,12 @@ Opc = RISCV::SUB; } - Register ScratchReg = MRI.createVirtualRegister(&RISCV::GPRRegClass); - TII->movImm32(MBB, MBBI, DL, ScratchReg, Val, Flag); + Register ScratchReg = TII->getTempReg(MBB.getParent(), Flag); + TII->movImm(MBB, MBBI, DL, ScratchReg, Val, Flag); BuildMI(MBB, MBBI, DL, TII->get(Opc), DestReg) .addReg(SrcReg) .addReg(ScratchReg, RegState::Kill) .setMIFlag(Flag); - } else { - report_fatal_error("adjustReg cannot yet handle adjustments >32 bits"); } } Index: lib/Target/RISCV/RISCVInstrInfo.h =================================================================== --- lib/Target/RISCV/RISCVInstrInfo.h +++ lib/Target/RISCV/RISCVInstrInfo.h @@ -46,10 +46,12 @@ int FrameIndex, const TargetRegisterClass *RC, const TargetRegisterInfo *TRI) const override; - // Materializes the given int32 Val into DstReg. - void movImm32(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, - const DebugLoc &DL, Register DstReg, uint64_t Val, - MachineInstr::MIFlag Flag = MachineInstr::NoFlags) const; + Register getTempReg(MachineFunction *MF, MachineInstr::MIFlag Flag) const; + + // Materializes the given integer Val into DstReg. + void movImm(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, + const DebugLoc &DL, Register DstReg, uint64_t Val, + MachineInstr::MIFlag Flag = MachineInstr::NoFlags) const; unsigned getInstSizeInBytes(const MachineInstr &MI) const override; Index: lib/Target/RISCV/RISCVInstrInfo.cpp =================================================================== --- lib/Target/RISCV/RISCVInstrInfo.cpp +++ lib/Target/RISCV/RISCVInstrInfo.cpp @@ -14,6 +14,7 @@ #include "RISCV.h" #include "RISCVSubtarget.h" #include "RISCVTargetMachine.h" +#include "Utils/RISCVMatInt.h" #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/SmallVector.h" #include "llvm/CodeGen/MachineFunctionPass.h" @@ -156,24 +157,61 @@ BuildMI(MBB, I, DL, get(Opcode), DstReg).addFrameIndex(FI).addImm(0); } -void RISCVInstrInfo::movImm32(MachineBasicBlock &MBB, - MachineBasicBlock::iterator MBBI, - const DebugLoc &DL, Register DstReg, uint64_t Val, - MachineInstr::MIFlag Flag) const { - assert(isInt<32>(Val) && "Can only materialize 32-bit constants"); - - // TODO: If the value can be materialized using only one instruction, only - // insert a single instruction. - - uint64_t Hi20 = ((Val + 0x800) >> 12) & 0xfffff; - uint64_t Lo12 = SignExtend64<12>(Val); - BuildMI(MBB, MBBI, DL, get(RISCV::LUI), DstReg) - .addImm(Hi20) - .setMIFlag(Flag); - BuildMI(MBB, MBBI, DL, get(RISCV::ADDI), DstReg) - .addReg(DstReg, RegState::Kill) - .addImm(Lo12) - .setMIFlag(Flag); +Register RISCVInstrInfo::getTempReg(MachineFunction *MF, + MachineInstr::MIFlag Flag) const { + MachineRegisterInfo &MRI = MF->getRegInfo(); + const MachineFrameInfo &MFI = MF->getFrameInfo(); + unsigned TempReg; + + // We can use T1 as temp register if the instructions are for FrameSetup or + // FrameDestroy and there is no shrink wrap optimization occur. + if (((Flag == MachineInstr::FrameSetup) && (MFI.getSavePoint() == nullptr)) || + ((Flag == MachineInstr::FrameDestroy) && + (MFI.getRestorePoint() == nullptr))) { + TempReg = RISCV::X6; + } else { + TempReg = MRI.createVirtualRegister(&RISCV::GPRRegClass); + } + + return TempReg; +} + +void RISCVInstrInfo::movImm(MachineBasicBlock &MBB, + MachineBasicBlock::iterator MBBI, + const DebugLoc &DL, Register DstReg, uint64_t Val, + MachineInstr::MIFlag Flag) const { + MachineFunction *MF = MBB.getParent(); + bool IsRV64 = MF->getSubtarget().is64Bit(); + Register SrcReg = RISCV::X0; + Register Result = getTempReg(MF, Flag); + unsigned Num = 0; + + if (!IsRV64 && !isInt<32>(Val)) + report_fatal_error("Should only materialize 32-bit constants for RV32"); + + RISCVMatInt::InstSeq Seq; + RISCVMatInt::generateInstSeq(Val, IsRV64, Seq); + assert(Seq.size() > 0); + + for (RISCVMatInt::Inst &Inst : Seq) { + // Write the final result to DstReg if it's the last instruction in the Seq. + // Otherwise, write the result to the temp register. + if (++Num == Seq.size()) + Result = DstReg; + + if (Inst.Opc == RISCV::LUI) { + BuildMI(MBB, MBBI, DL, get(RISCV::LUI), Result) + .addImm(Inst.Imm) + .setMIFlag(Flag); + } else { + BuildMI(MBB, MBBI, DL, get(Inst.Opc), Result) + .addReg(SrcReg, RegState::Kill) + .addImm(Inst.Imm) + .setMIFlag(Flag); + } + // Only the first instruction has X0 as its source. + SrcReg = Result; + } } // The contents of values added to Cond are not examined outside of Index: lib/Target/RISCV/RISCVRegisterInfo.cpp =================================================================== --- lib/Target/RISCV/RISCVRegisterInfo.cpp +++ lib/Target/RISCV/RISCVRegisterInfo.cpp @@ -110,7 +110,7 @@ // The offset won't fit in an immediate, so use a scratch register instead // Modify Offset and FrameReg appropriately Register ScratchReg = MRI.createVirtualRegister(&RISCV::GPRRegClass); - TII->movImm32(MBB, II, DL, ScratchReg, Offset); + TII->movImm(MBB, II, DL, ScratchReg, Offset); BuildMI(MBB, II, DL, TII->get(RISCV::ADD), ScratchReg) .addReg(FrameReg) .addReg(ScratchReg, RegState::Kill); Index: test/CodeGen/RISCV/large-stack.ll =================================================================== --- test/CodeGen/RISCV/large-stack.ll +++ test/CodeGen/RISCV/large-stack.ll @@ -9,19 +9,19 @@ define void @test() nounwind { ; RV32I-FPELIM-LABEL: test: ; RV32I-FPELIM: # %bb.0: -; RV32I-FPELIM-NEXT: lui a0, 74565 -; RV32I-FPELIM-NEXT: addi a0, a0, 1664 -; RV32I-FPELIM-NEXT: sub sp, sp, a0 -; RV32I-FPELIM-NEXT: lui a0, 74565 -; RV32I-FPELIM-NEXT: addi a0, a0, 1664 -; RV32I-FPELIM-NEXT: add sp, sp, a0 +; RV32I-FPELIM-NEXT: lui t1, 74565 +; RV32I-FPELIM-NEXT: addi t1, t1, 1664 +; RV32I-FPELIM-NEXT: sub sp, sp, t1 +; RV32I-FPELIM-NEXT: lui t1, 74565 +; RV32I-FPELIM-NEXT: addi t1, t1, 1664 +; RV32I-FPELIM-NEXT: add sp, sp, t1 ; RV32I-FPELIM-NEXT: ret ; ; RV32I-WITHFP-LABEL: test: ; RV32I-WITHFP: # %bb.0: -; RV32I-WITHFP-NEXT: lui a0, 74565 -; RV32I-WITHFP-NEXT: addi a0, a0, 1680 -; RV32I-WITHFP-NEXT: sub sp, sp, a0 +; RV32I-WITHFP-NEXT: lui t1, 74565 +; RV32I-WITHFP-NEXT: addi t1, t1, 1680 +; RV32I-WITHFP-NEXT: sub sp, sp, t1 ; RV32I-WITHFP-NEXT: lui a0, 74565 ; RV32I-WITHFP-NEXT: addi a0, a0, 1676 ; RV32I-WITHFP-NEXT: add a0, sp, a0 @@ -30,9 +30,9 @@ ; RV32I-WITHFP-NEXT: addi a0, a0, 1672 ; RV32I-WITHFP-NEXT: add a0, sp, a0 ; RV32I-WITHFP-NEXT: sw s0, 0(a0) -; RV32I-WITHFP-NEXT: lui a0, 74565 -; RV32I-WITHFP-NEXT: addi a0, a0, 1680 -; RV32I-WITHFP-NEXT: add s0, sp, a0 +; RV32I-WITHFP-NEXT: lui t1, 74565 +; RV32I-WITHFP-NEXT: addi t1, t1, 1680 +; RV32I-WITHFP-NEXT: add s0, sp, t1 ; RV32I-WITHFP-NEXT: lui a0, 74565 ; RV32I-WITHFP-NEXT: addi a0, a0, 1672 ; RV32I-WITHFP-NEXT: add a0, sp, a0 @@ -41,9 +41,9 @@ ; RV32I-WITHFP-NEXT: addi a0, a0, 1676 ; RV32I-WITHFP-NEXT: add a0, sp, a0 ; RV32I-WITHFP-NEXT: lw ra, 0(a0) -; RV32I-WITHFP-NEXT: lui a0, 74565 -; RV32I-WITHFP-NEXT: addi a0, a0, 1680 -; RV32I-WITHFP-NEXT: add sp, sp, a0 +; RV32I-WITHFP-NEXT: lui t1, 74565 +; RV32I-WITHFP-NEXT: addi t1, t1, 1680 +; RV32I-WITHFP-NEXT: add sp, sp, t1 ; RV32I-WITHFP-NEXT: ret %tmp = alloca [ 305419896 x i8 ] , align 4 ret void @@ -55,9 +55,9 @@ define void @test_emergency_spill_slot(i32 %a) nounwind { ; RV32I-FPELIM-LABEL: test_emergency_spill_slot: ; RV32I-FPELIM: # %bb.0: -; RV32I-FPELIM-NEXT: lui a1, 98 -; RV32I-FPELIM-NEXT: addi a1, a1, -1392 -; RV32I-FPELIM-NEXT: sub sp, sp, a1 +; RV32I-FPELIM-NEXT: lui t1, 98 +; RV32I-FPELIM-NEXT: addi t1, t1, -1392 +; RV32I-FPELIM-NEXT: sub sp, sp, t1 ; RV32I-FPELIM-NEXT: lui a1, 98 ; RV32I-FPELIM-NEXT: addi a1, a1, -1396 ; RV32I-FPELIM-NEXT: add a1, sp, a1 @@ -85,16 +85,16 @@ ; RV32I-FPELIM-NEXT: addi a0, a0, -1396 ; RV32I-FPELIM-NEXT: add a0, sp, a0 ; RV32I-FPELIM-NEXT: lw s0, 0(a0) -; RV32I-FPELIM-NEXT: lui a0, 98 -; RV32I-FPELIM-NEXT: addi a0, a0, -1392 -; RV32I-FPELIM-NEXT: add sp, sp, a0 +; RV32I-FPELIM-NEXT: lui t1, 98 +; RV32I-FPELIM-NEXT: addi t1, t1, -1392 +; RV32I-FPELIM-NEXT: add sp, sp, t1 ; RV32I-FPELIM-NEXT: ret ; ; RV32I-WITHFP-LABEL: test_emergency_spill_slot: ; RV32I-WITHFP: # %bb.0: -; RV32I-WITHFP-NEXT: lui a1, 98 -; RV32I-WITHFP-NEXT: addi a1, a1, -1376 -; RV32I-WITHFP-NEXT: sub sp, sp, a1 +; RV32I-WITHFP-NEXT: lui t1, 98 +; RV32I-WITHFP-NEXT: addi t1, t1, -1376 +; RV32I-WITHFP-NEXT: sub sp, sp, t1 ; RV32I-WITHFP-NEXT: lui a1, 98 ; RV32I-WITHFP-NEXT: addi a1, a1, -1380 ; RV32I-WITHFP-NEXT: add a1, sp, a1 @@ -111,9 +111,9 @@ ; RV32I-WITHFP-NEXT: addi a1, a1, -1392 ; RV32I-WITHFP-NEXT: add a1, sp, a1 ; RV32I-WITHFP-NEXT: sw s2, 0(a1) -; RV32I-WITHFP-NEXT: lui a1, 98 -; RV32I-WITHFP-NEXT: addi a1, a1, -1376 -; RV32I-WITHFP-NEXT: add s0, sp, a1 +; RV32I-WITHFP-NEXT: lui t1, 98 +; RV32I-WITHFP-NEXT: addi t1, t1, -1376 +; RV32I-WITHFP-NEXT: add s0, sp, t1 ; RV32I-WITHFP-NEXT: lui a1, 78 ; RV32I-WITHFP-NEXT: addi a1, a1, 512 ; RV32I-WITHFP-NEXT: lui a2, 1048478 @@ -144,9 +144,9 @@ ; RV32I-WITHFP-NEXT: addi a0, a0, -1380 ; RV32I-WITHFP-NEXT: add a0, sp, a0 ; RV32I-WITHFP-NEXT: lw ra, 0(a0) -; RV32I-WITHFP-NEXT: lui a0, 98 -; RV32I-WITHFP-NEXT: addi a0, a0, -1376 -; RV32I-WITHFP-NEXT: add sp, sp, a0 +; RV32I-WITHFP-NEXT: lui t1, 98 +; RV32I-WITHFP-NEXT: addi t1, t1, -1376 +; RV32I-WITHFP-NEXT: add sp, sp, t1 ; RV32I-WITHFP-NEXT: ret %data = alloca [ 100000 x i32 ] , align 4 %ptr = getelementptr inbounds [100000 x i32], [100000 x i32]* %data, i32 0, i32 80000 Index: test/CodeGen/RISCV/rv64-large-stack.ll =================================================================== --- /dev/null +++ test/CodeGen/RISCV/rv64-large-stack.ll @@ -0,0 +1,38 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +; RUN: llc -mtriple=riscv64 -verify-machineinstrs < %s | FileCheck %s +; +; The test case check that RV64 could handle the stack adjustment offset exceed +; 32-bit. + +define void @foo() nounwind { +; CHECK-LABEL: foo: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: lui t1, 95 +; CHECK-NEXT: addiw t1, t1, 1505 +; CHECK-NEXT: slli t1, t1, 13 +; CHECK-NEXT: addi t1, t1, 32 +; CHECK-NEXT: sub sp, sp, t1 +; CHECK-NEXT: lui a0, 781250 +; CHECK-NEXT: addiw a0, a0, 24 +; CHECK-NEXT: add a0, sp, a0 +; CHECK-NEXT: sd ra, 0(a0) +; CHECK-NEXT: addi a0, sp, 16 +; CHECK-NEXT: call baz +; CHECK-NEXT: lui a0, 781250 +; CHECK-NEXT: addiw a0, a0, 24 +; CHECK-NEXT: add a0, sp, a0 +; CHECK-NEXT: ld ra, 0(a0) +; CHECK-NEXT: lui t1, 95 +; CHECK-NEXT: addiw t1, t1, 1505 +; CHECK-NEXT: slli t1, t1, 13 +; CHECK-NEXT: addi t1, t1, 32 +; CHECK-NEXT: add sp, sp, t1 +; CHECK-NEXT: ret +entry: + %w = alloca [100000000 x { fp128, fp128 }], align 16 + %arraydecay = getelementptr inbounds [100000000 x { fp128, fp128 }], [100000000 x { fp128, fp128 }]* %w, i64 0, i64 0 + call void @baz({ fp128, fp128 }* nonnull %arraydecay) + ret void +} + +declare void @baz({ fp128, fp128 }*) Index: test/CodeGen/RISCV/stack-realignment.ll =================================================================== --- test/CodeGen/RISCV/stack-realignment.ll +++ test/CodeGen/RISCV/stack-realignment.ll @@ -309,9 +309,9 @@ define void @caller1024() nounwind { ; RV32I-LABEL: caller1024: ; RV32I: # %bb.0: -; RV32I-NEXT: lui a0, 1 -; RV32I-NEXT: addi a0, a0, -1024 -; RV32I-NEXT: sub sp, sp, a0 +; RV32I-NEXT: lui t1, 1 +; RV32I-NEXT: addi t1, t1, -1024 +; RV32I-NEXT: sub sp, sp, t1 ; RV32I-NEXT: lui a0, 1 ; RV32I-NEXT: addi a0, a0, -1028 ; RV32I-NEXT: add a0, sp, a0 @@ -320,18 +320,18 @@ ; RV32I-NEXT: addi a0, a0, -1032 ; RV32I-NEXT: add a0, sp, a0 ; RV32I-NEXT: sw s0, 0(a0) -; RV32I-NEXT: lui a0, 1 -; RV32I-NEXT: addi a0, a0, -1024 -; RV32I-NEXT: add s0, sp, a0 +; RV32I-NEXT: lui t1, 1 +; RV32I-NEXT: addi t1, t1, -1024 +; RV32I-NEXT: add s0, sp, t1 ; RV32I-NEXT: andi sp, sp, -1024 ; RV32I-NEXT: lui a0, 1 ; RV32I-NEXT: addi a0, a0, -2048 ; RV32I-NEXT: add a0, sp, a0 ; RV32I-NEXT: mv a0, a0 ; RV32I-NEXT: call callee -; RV32I-NEXT: lui a0, 1 -; RV32I-NEXT: addi a0, a0, -1024 -; RV32I-NEXT: sub sp, s0, a0 +; RV32I-NEXT: lui t1, 1 +; RV32I-NEXT: addi t1, t1, -1024 +; RV32I-NEXT: sub sp, s0, t1 ; RV32I-NEXT: lui a0, 1 ; RV32I-NEXT: addi a0, a0, -1032 ; RV32I-NEXT: add a0, sp, a0 @@ -340,47 +340,47 @@ ; RV32I-NEXT: addi a0, a0, -1028 ; RV32I-NEXT: add a0, sp, a0 ; RV32I-NEXT: lw ra, 0(a0) -; RV32I-NEXT: lui a0, 1 -; RV32I-NEXT: addi a0, a0, -1024 -; RV32I-NEXT: add sp, sp, a0 +; RV32I-NEXT: lui t1, 1 +; RV32I-NEXT: addi t1, t1, -1024 +; RV32I-NEXT: add sp, sp, t1 ; RV32I-NEXT: ret ; ; RV64I-LABEL: caller1024: ; RV64I: # %bb.0: +; RV64I-NEXT: lui t1, 1 +; RV64I-NEXT: addiw t1, t1, -1024 +; RV64I-NEXT: sub sp, sp, t1 ; RV64I-NEXT: lui a0, 1 -; RV64I-NEXT: addi a0, a0, -1024 -; RV64I-NEXT: sub sp, sp, a0 -; RV64I-NEXT: lui a0, 1 -; RV64I-NEXT: addi a0, a0, -1032 +; RV64I-NEXT: addiw a0, a0, -1032 ; RV64I-NEXT: add a0, sp, a0 ; RV64I-NEXT: sd ra, 0(a0) ; RV64I-NEXT: lui a0, 1 -; RV64I-NEXT: addi a0, a0, -1040 +; RV64I-NEXT: addiw a0, a0, -1040 ; RV64I-NEXT: add a0, sp, a0 ; RV64I-NEXT: sd s0, 0(a0) -; RV64I-NEXT: lui a0, 1 -; RV64I-NEXT: addi a0, a0, -1024 -; RV64I-NEXT: add s0, sp, a0 +; RV64I-NEXT: lui t1, 1 +; RV64I-NEXT: addiw t1, t1, -1024 +; RV64I-NEXT: add s0, sp, t1 ; RV64I-NEXT: andi sp, sp, -1024 ; RV64I-NEXT: lui a0, 1 -; RV64I-NEXT: addi a0, a0, -2048 +; RV64I-NEXT: addiw a0, a0, -2048 ; RV64I-NEXT: add a0, sp, a0 ; RV64I-NEXT: mv a0, a0 ; RV64I-NEXT: call callee +; RV64I-NEXT: lui t1, 1 +; RV64I-NEXT: addiw t1, t1, -1024 +; RV64I-NEXT: sub sp, s0, t1 ; RV64I-NEXT: lui a0, 1 -; RV64I-NEXT: addi a0, a0, -1024 -; RV64I-NEXT: sub sp, s0, a0 -; RV64I-NEXT: lui a0, 1 -; RV64I-NEXT: addi a0, a0, -1040 +; RV64I-NEXT: addiw a0, a0, -1040 ; RV64I-NEXT: add a0, sp, a0 ; RV64I-NEXT: ld s0, 0(a0) ; RV64I-NEXT: lui a0, 1 -; RV64I-NEXT: addi a0, a0, -1032 +; RV64I-NEXT: addiw a0, a0, -1032 ; RV64I-NEXT: add a0, sp, a0 ; RV64I-NEXT: ld ra, 0(a0) -; RV64I-NEXT: lui a0, 1 -; RV64I-NEXT: addi a0, a0, -1024 -; RV64I-NEXT: add sp, sp, a0 +; RV64I-NEXT: lui t1, 1 +; RV64I-NEXT: addiw t1, t1, -1024 +; RV64I-NEXT: add sp, sp, t1 ; RV64I-NEXT: ret %1 = alloca i8, align 1024 call void @callee(i8* %1) @@ -415,9 +415,9 @@ define void @caller2048() nounwind { ; RV32I-LABEL: caller2048: ; RV32I: # %bb.0: -; RV32I-NEXT: lui a0, 2 -; RV32I-NEXT: addi a0, a0, -2048 -; RV32I-NEXT: sub sp, sp, a0 +; RV32I-NEXT: lui t1, 2 +; RV32I-NEXT: addi t1, t1, -2048 +; RV32I-NEXT: sub sp, sp, t1 ; RV32I-NEXT: lui a0, 1 ; RV32I-NEXT: addi a0, a0, 2044 ; RV32I-NEXT: add a0, sp, a0 @@ -426,18 +426,17 @@ ; RV32I-NEXT: addi a0, a0, 2040 ; RV32I-NEXT: add a0, sp, a0 ; RV32I-NEXT: sw s0, 0(a0) -; RV32I-NEXT: lui a0, 2 -; RV32I-NEXT: addi a0, a0, -2048 -; RV32I-NEXT: add s0, sp, a0 +; RV32I-NEXT: lui t1, 2 +; RV32I-NEXT: addi t1, t1, -2048 +; RV32I-NEXT: add s0, sp, t1 ; RV32I-NEXT: andi sp, sp, -2048 ; RV32I-NEXT: lui a0, 1 -; RV32I-NEXT: mv a0, a0 ; RV32I-NEXT: add a0, sp, a0 ; RV32I-NEXT: mv a0, a0 ; RV32I-NEXT: call callee -; RV32I-NEXT: lui a0, 2 -; RV32I-NEXT: addi a0, a0, -2048 -; RV32I-NEXT: sub sp, s0, a0 +; RV32I-NEXT: lui t1, 2 +; RV32I-NEXT: addi t1, t1, -2048 +; RV32I-NEXT: sub sp, s0, t1 ; RV32I-NEXT: lui a0, 1 ; RV32I-NEXT: addi a0, a0, 2040 ; RV32I-NEXT: add a0, sp, a0 @@ -446,47 +445,46 @@ ; RV32I-NEXT: addi a0, a0, 2044 ; RV32I-NEXT: add a0, sp, a0 ; RV32I-NEXT: lw ra, 0(a0) -; RV32I-NEXT: lui a0, 2 -; RV32I-NEXT: addi a0, a0, -2048 -; RV32I-NEXT: add sp, sp, a0 +; RV32I-NEXT: lui t1, 2 +; RV32I-NEXT: addi t1, t1, -2048 +; RV32I-NEXT: add sp, sp, t1 ; RV32I-NEXT: ret ; ; RV64I-LABEL: caller2048: ; RV64I: # %bb.0: -; RV64I-NEXT: lui a0, 2 -; RV64I-NEXT: addi a0, a0, -2048 -; RV64I-NEXT: sub sp, sp, a0 +; RV64I-NEXT: lui t1, 2 +; RV64I-NEXT: addiw t1, t1, -2048 +; RV64I-NEXT: sub sp, sp, t1 ; RV64I-NEXT: lui a0, 1 -; RV64I-NEXT: addi a0, a0, 2040 +; RV64I-NEXT: addiw a0, a0, 2040 ; RV64I-NEXT: add a0, sp, a0 ; RV64I-NEXT: sd ra, 0(a0) ; RV64I-NEXT: lui a0, 1 -; RV64I-NEXT: addi a0, a0, 2032 +; RV64I-NEXT: addiw a0, a0, 2032 ; RV64I-NEXT: add a0, sp, a0 ; RV64I-NEXT: sd s0, 0(a0) -; RV64I-NEXT: lui a0, 2 -; RV64I-NEXT: addi a0, a0, -2048 -; RV64I-NEXT: add s0, sp, a0 +; RV64I-NEXT: lui t1, 2 +; RV64I-NEXT: addiw t1, t1, -2048 +; RV64I-NEXT: add s0, sp, t1 ; RV64I-NEXT: andi sp, sp, -2048 ; RV64I-NEXT: lui a0, 1 -; RV64I-NEXT: mv a0, a0 ; RV64I-NEXT: add a0, sp, a0 ; RV64I-NEXT: mv a0, a0 ; RV64I-NEXT: call callee -; RV64I-NEXT: lui a0, 2 -; RV64I-NEXT: addi a0, a0, -2048 -; RV64I-NEXT: sub sp, s0, a0 +; RV64I-NEXT: lui t1, 2 +; RV64I-NEXT: addiw t1, t1, -2048 +; RV64I-NEXT: sub sp, s0, t1 ; RV64I-NEXT: lui a0, 1 -; RV64I-NEXT: addi a0, a0, 2032 +; RV64I-NEXT: addiw a0, a0, 2032 ; RV64I-NEXT: add a0, sp, a0 ; RV64I-NEXT: ld s0, 0(a0) ; RV64I-NEXT: lui a0, 1 -; RV64I-NEXT: addi a0, a0, 2040 +; RV64I-NEXT: addiw a0, a0, 2040 ; RV64I-NEXT: add a0, sp, a0 ; RV64I-NEXT: ld ra, 0(a0) -; RV64I-NEXT: lui a0, 2 -; RV64I-NEXT: addi a0, a0, -2048 -; RV64I-NEXT: add sp, sp, a0 +; RV64I-NEXT: lui t1, 2 +; RV64I-NEXT: addiw t1, t1, -2048 +; RV64I-NEXT: add sp, sp, t1 ; RV64I-NEXT: ret %1 = alloca i8, align 2048 call void @callee(i8* %1) @@ -521,9 +519,8 @@ define void @caller4096() nounwind { ; RV32I-LABEL: caller4096: ; RV32I: # %bb.0: -; RV32I-NEXT: lui a0, 3 -; RV32I-NEXT: mv a0, a0 -; RV32I-NEXT: sub sp, sp, a0 +; RV32I-NEXT: lui t1, 3 +; RV32I-NEXT: sub sp, sp, t1 ; RV32I-NEXT: lui a0, 3 ; RV32I-NEXT: addi a0, a0, -4 ; RV32I-NEXT: add a0, sp, a0 @@ -532,19 +529,16 @@ ; RV32I-NEXT: addi a0, a0, -8 ; RV32I-NEXT: add a0, sp, a0 ; RV32I-NEXT: sw s0, 0(a0) -; RV32I-NEXT: lui a0, 3 -; RV32I-NEXT: mv a0, a0 -; RV32I-NEXT: add s0, sp, a0 +; RV32I-NEXT: lui t1, 3 +; RV32I-NEXT: add s0, sp, t1 ; RV32I-NEXT: srli a0, sp, 12 ; RV32I-NEXT: slli sp, a0, 12 ; RV32I-NEXT: lui a0, 2 -; RV32I-NEXT: mv a0, a0 ; RV32I-NEXT: add a0, sp, a0 ; RV32I-NEXT: mv a0, a0 ; RV32I-NEXT: call callee -; RV32I-NEXT: lui a0, 3 -; RV32I-NEXT: mv a0, a0 -; RV32I-NEXT: sub sp, s0, a0 +; RV32I-NEXT: lui t1, 3 +; RV32I-NEXT: sub sp, s0, t1 ; RV32I-NEXT: lui a0, 3 ; RV32I-NEXT: addi a0, a0, -8 ; RV32I-NEXT: add a0, sp, a0 @@ -553,48 +547,42 @@ ; RV32I-NEXT: addi a0, a0, -4 ; RV32I-NEXT: add a0, sp, a0 ; RV32I-NEXT: lw ra, 0(a0) -; RV32I-NEXT: lui a0, 3 -; RV32I-NEXT: mv a0, a0 -; RV32I-NEXT: add sp, sp, a0 +; RV32I-NEXT: lui t1, 3 +; RV32I-NEXT: add sp, sp, t1 ; RV32I-NEXT: ret ; ; RV64I-LABEL: caller4096: ; RV64I: # %bb.0: +; RV64I-NEXT: lui t1, 3 +; RV64I-NEXT: sub sp, sp, t1 ; RV64I-NEXT: lui a0, 3 -; RV64I-NEXT: mv a0, a0 -; RV64I-NEXT: sub sp, sp, a0 -; RV64I-NEXT: lui a0, 3 -; RV64I-NEXT: addi a0, a0, -8 +; RV64I-NEXT: addiw a0, a0, -8 ; RV64I-NEXT: add a0, sp, a0 ; RV64I-NEXT: sd ra, 0(a0) ; RV64I-NEXT: lui a0, 3 -; RV64I-NEXT: addi a0, a0, -16 +; RV64I-NEXT: addiw a0, a0, -16 ; RV64I-NEXT: add a0, sp, a0 ; RV64I-NEXT: sd s0, 0(a0) -; RV64I-NEXT: lui a0, 3 -; RV64I-NEXT: mv a0, a0 -; RV64I-NEXT: add s0, sp, a0 +; RV64I-NEXT: lui t1, 3 +; RV64I-NEXT: add s0, sp, t1 ; RV64I-NEXT: srli a0, sp, 12 ; RV64I-NEXT: slli sp, a0, 12 ; RV64I-NEXT: lui a0, 2 -; RV64I-NEXT: mv a0, a0 ; RV64I-NEXT: add a0, sp, a0 ; RV64I-NEXT: mv a0, a0 ; RV64I-NEXT: call callee +; RV64I-NEXT: lui t1, 3 +; RV64I-NEXT: sub sp, s0, t1 ; RV64I-NEXT: lui a0, 3 -; RV64I-NEXT: mv a0, a0 -; RV64I-NEXT: sub sp, s0, a0 -; RV64I-NEXT: lui a0, 3 -; RV64I-NEXT: addi a0, a0, -16 +; RV64I-NEXT: addiw a0, a0, -16 ; RV64I-NEXT: add a0, sp, a0 ; RV64I-NEXT: ld s0, 0(a0) ; RV64I-NEXT: lui a0, 3 -; RV64I-NEXT: addi a0, a0, -8 +; RV64I-NEXT: addiw a0, a0, -8 ; RV64I-NEXT: add a0, sp, a0 ; RV64I-NEXT: ld ra, 0(a0) -; RV64I-NEXT: lui a0, 3 -; RV64I-NEXT: mv a0, a0 -; RV64I-NEXT: add sp, sp, a0 +; RV64I-NEXT: lui t1, 3 +; RV64I-NEXT: add sp, sp, t1 ; RV64I-NEXT: ret %1 = alloca i8, align 4096 call void @callee(i8* %1)