Index: lib/Target/RISCV/RISCVFrameLowering.h =================================================================== --- lib/Target/RISCV/RISCVFrameLowering.h +++ lib/Target/RISCV/RISCVFrameLowering.h @@ -43,9 +43,7 @@ MachineBasicBlock::iterator eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB, - MachineBasicBlock::iterator MI) const override { - return MBB.erase(MI); - } + MachineBasicBlock::iterator MI) const override; protected: const RISCVSubtarget &STI; Index: lib/Target/RISCV/RISCVFrameLowering.cpp =================================================================== --- lib/Target/RISCV/RISCVFrameLowering.cpp +++ lib/Target/RISCV/RISCVFrameLowering.cpp @@ -246,3 +246,34 @@ RS->addScavengingFrameIndex(RegScavFI); } } + +// Eliminate ADJCALLSTACKDOWN, ADJCALLSTACKUP pseudo instructions +MachineBasicBlock::iterator RISCVFrameLowering:: +eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB, + MachineBasicBlock::iterator MI) const { + unsigned SPReg = RISCV::X2; + DebugLoc DL = MI->getDebugLoc(); + + if (!hasReservedCallFrame(MF)) { + // If we have alloca, convert as follows: + // ADJCALLSTACKDOWN -> sub, sp, sp, amount + // ADJCALLSTACKUP -> add, sp, sp, amount + // + // To avoid alloca area poison by outgoing arguments. + int64_t Amount = MI->getOperand(0).getImm(); + + if (Amount != 0) { + // We need to keep the stack aligned properly. To do this, we round the + // amount of space needed for the outgoing arguments up to the next + // alignment boundary. + Amount = alignSPAdjust(Amount); + + if (MI->getOpcode() == RISCV::ADJCALLSTACKDOWN) + Amount = -Amount; + + adjustReg(MBB, MI, DL, SPReg, SPReg, Amount, MachineInstr::NoFlags); + } + } + + return MBB.erase(MI); +} Index: test/CodeGen/RISCV/alloca.ll =================================================================== --- test/CodeGen/RISCV/alloca.ll +++ test/CodeGen/RISCV/alloca.ll @@ -63,3 +63,99 @@ call void @llvm.stackrestore(i8* %sp) ret void } + +; Function Attrs: noinline nounwind +define void @bar(i32 %x) local_unnamed_addr { +; RV32I-LABEL: bar: +; RV32I: # %bb.0: # %entry +; RV32I-NEXT: addi sp, sp, -80 +; RV32I-NEXT: sw ra, 76(sp) +; RV32I-NEXT: sw s0, 72(sp) +; RV32I-NEXT: addi s0, sp, 80 +; RV32I-NEXT: addi a1, a0, 15 +; RV32I-NEXT: andi a1, a1, -16 +; RV32I-NEXT: sub a1, sp, a1 +; RV32I-NEXT: mv sp, a1 +; RV32I-NEXT: addi a2, zero, 4 +; RV32I-NEXT: bltu a0, a2, .LBB2_3 +; RV32I-NEXT: # %bb.1: # %if.then +; RV32I-NEXT: lui a0, 1783 +; RV32I-NEXT: addi a0, a0, -154 +; RV32I-NEXT: sw a0, 0(a1) +; RV32I-NEXT: bnez zero, .LBB2_4 +; RV32I-NEXT: # %bb.2: # %if.then3 +; RV32I-NEXT: .LBB2_3: # %if.end4.critedge +; RV32I-NEXT: addi sp, sp, -64 +; RV32I-NEXT: sw a1, 48(sp) +; RV32I-NEXT: lui a0, 267520 +; RV32I-NEXT: mv a0, a0 +; RV32I-NEXT: sw a0, 44(sp) +; RV32I-NEXT: lui a0, 267264 +; RV32I-NEXT: mv a0, a0 +; RV32I-NEXT: sw a0, 40(sp) +; RV32I-NEXT: lui a0, 267008 +; RV32I-NEXT: mv a0, a0 +; RV32I-NEXT: sw a0, 36(sp) +; RV32I-NEXT: lui a0, 266752 +; RV32I-NEXT: mv a0, a0 +; RV32I-NEXT: sw a0, 32(sp) +; RV32I-NEXT: lui a0, 262592 +; RV32I-NEXT: mv a0, a0 +; RV32I-NEXT: sw a0, 28(sp) +; RV32I-NEXT: lui a0, 262528 +; RV32I-NEXT: mv a0, a0 +; RV32I-NEXT: sw a0, 20(sp) +; RV32I-NEXT: lui a0, 262464 +; RV32I-NEXT: mv a0, a0 +; RV32I-NEXT: sw a0, 12(sp) +; RV32I-NEXT: lui a0, 262400 +; RV32I-NEXT: mv a0, a0 +; RV32I-NEXT: sw a0, 4(sp) +; RV32I-NEXT: sw zero, 24(sp) +; RV32I-NEXT: sw zero, 16(sp) +; RV32I-NEXT: sw zero, 8(sp) +; RV32I-NEXT: sw zero, 0(sp) +; RV32I-NEXT: lui a0, 261888 +; RV32I-NEXT: mv a3, a0 +; RV32I-NEXT: lui a0, 262144 +; RV32I-NEXT: mv a5, a0 +; RV32I-NEXT: lui a0, 262272 +; RV32I-NEXT: mv a7, a0 +; RV32I-NEXT: lui a0, %hi(foo) +; RV32I-NEXT: addi t0, a0, %lo(foo) +; RV32I-NEXT: mv a0, zero +; RV32I-NEXT: mv a1, zero +; RV32I-NEXT: mv a2, zero +; RV32I-NEXT: mv a4, zero +; RV32I-NEXT: mv a6, zero +; RV32I-NEXT: jalr t0 +; RV32I-NEXT: addi sp, sp, 64 +; RV32I-NEXT: .LBB2_4: # %if.end4 +; RV32I-NEXT: addi sp, s0, -80 +; RV32I-NEXT: lw s0, 72(sp) +; RV32I-NEXT: lw ra, 76(sp) +; RV32I-NEXT: addi sp, sp, 80 +; RV32I-NEXT: ret +entry: + %vla = alloca i8, i32 %x, align 4 + %cmp = icmp ugt i32 %x, 3 + br i1 %cmp, label %if.then, label %if.end4.critedge + +if.then: ; preds = %entry + %0 = bitcast i8* %vla to i32* + store i32 7303014, i32* %0, align 4 + %lhsv = load i32, i32* %0, align 4 + %1 = icmp eq i32 %lhsv, 7496034 + br i1 %1, label %if.end4, label %if.then3 + +if.then3: ; preds = %if.then + unreachable + +if.end4.critedge: ; preds = %entry + call void @foo(double 0.000000e+00, double 1.000000e+00, double 2.000000e+00, double 3.000000e+00, double 4.000000e+00, double 5.000000e+00, double 6.000000e+00, double 7.000000e+00, float 1.000000e+01, float 1.100000e+01, float 1.200000e+01, float 1.300000e+01, i8* nonnull %vla) #3 + br label %if.end4 +if.end4: ; preds = %if.end4.critedge, %if.then + ret void +} + +declare void @foo(double, double, double, double, double, double, double, double, float, float, float, float, i8*) local_unnamed_addr Index: test/CodeGen/RISCV/calling-conv.ll =================================================================== --- test/CodeGen/RISCV/calling-conv.ll +++ test/CodeGen/RISCV/calling-conv.ll @@ -338,6 +338,7 @@ ; RV32I-WITHFP-NEXT: sw ra, 60(sp) ; RV32I-WITHFP-NEXT: sw s0, 56(sp) ; RV32I-WITHFP-NEXT: addi s0, sp, 64 +; RV32I-WITHFP-NEXT: addi sp, sp, -16 ; RV32I-WITHFP-NEXT: addi a0, s0, -48 ; RV32I-WITHFP-NEXT: sw a0, 4(sp) ; RV32I-WITHFP-NEXT: addi a0, zero, 9 @@ -364,6 +365,7 @@ ; RV32I-WITHFP-NEXT: addi a6, zero, 7 ; RV32I-WITHFP-NEXT: addi a7, s0, -24 ; RV32I-WITHFP-NEXT: jalr t0 +; RV32I-WITHFP-NEXT: addi sp, sp, 16 ; RV32I-WITHFP-NEXT: lw s0, 56(sp) ; RV32I-WITHFP-NEXT: lw ra, 60(sp) ; RV32I-WITHFP-NEXT: addi sp, sp, 64 @@ -508,6 +510,7 @@ ; RV32I-WITHFP-NEXT: sw ra, 28(sp) ; RV32I-WITHFP-NEXT: sw s0, 24(sp) ; RV32I-WITHFP-NEXT: addi s0, sp, 32 +; RV32I-WITHFP-NEXT: addi sp, sp, -16 ; RV32I-WITHFP-NEXT: addi a0, zero, 8 ; RV32I-WITHFP-NEXT: sw a0, 4(sp) ; RV32I-WITHFP-NEXT: sw zero, 0(sp) @@ -522,6 +525,7 @@ ; RV32I-WITHFP-NEXT: addi a7, zero, 7 ; RV32I-WITHFP-NEXT: mv a4, zero ; RV32I-WITHFP-NEXT: jalr t0 +; RV32I-WITHFP-NEXT: addi sp, sp, 16 ; RV32I-WITHFP-NEXT: lw s0, 24(sp) ; RV32I-WITHFP-NEXT: lw ra, 28(sp) ; RV32I-WITHFP-NEXT: addi sp, sp, 32 @@ -798,6 +802,7 @@ ; RV32I-WITHFP-NEXT: sw ra, 60(sp) ; RV32I-WITHFP-NEXT: sw s0, 56(sp) ; RV32I-WITHFP-NEXT: addi s0, sp, 64 +; RV32I-WITHFP-NEXT: addi sp, sp, -32 ; RV32I-WITHFP-NEXT: addi a0, zero, 18 ; RV32I-WITHFP-NEXT: sw a0, 24(sp) ; RV32I-WITHFP-NEXT: addi a0, zero, 17 @@ -836,6 +841,7 @@ ; RV32I-WITHFP-NEXT: addi a6, zero, 4 ; RV32I-WITHFP-NEXT: addi a7, zero, 14 ; RV32I-WITHFP-NEXT: jalr t0 +; RV32I-WITHFP-NEXT: addi sp, sp, 32 ; RV32I-WITHFP-NEXT: lw s0, 56(sp) ; RV32I-WITHFP-NEXT: lw ra, 60(sp) ; RV32I-WITHFP-NEXT: addi sp, sp, 64 Index: test/CodeGen/RISCV/vararg.ll =================================================================== --- test/CodeGen/RISCV/vararg.ll +++ test/CodeGen/RISCV/vararg.ll @@ -1056,6 +1056,7 @@ ; RV32I-WITHFP-NEXT: sw ra, 60(sp) ; RV32I-WITHFP-NEXT: sw s0, 56(sp) ; RV32I-WITHFP-NEXT: addi s0, sp, 64 +; RV32I-WITHFP-NEXT: addi sp, sp, -32 ; RV32I-WITHFP-NEXT: addi a0, zero, 17 ; RV32I-WITHFP-NEXT: sw a0, 24(sp) ; RV32I-WITHFP-NEXT: addi a0, zero, 16 @@ -1093,6 +1094,7 @@ ; RV32I-WITHFP-NEXT: addi a4, zero, 13 ; RV32I-WITHFP-NEXT: addi a7, zero, 4 ; RV32I-WITHFP-NEXT: jalr a5 +; RV32I-WITHFP-NEXT: addi sp, sp, 32 ; RV32I-WITHFP-NEXT: lw s0, 56(sp) ; RV32I-WITHFP-NEXT: lw ra, 60(sp) ; RV32I-WITHFP-NEXT: addi sp, sp, 64