Skip to content

Commit

Permalink
[RISCV] Expand function call to "call" pseudoinstruction
Browse files Browse the repository at this point in the history
To do this:
1. Change GlobalAddress SDNode to TargetGlobalAddress to avoid legalizer
   split the symbol.

2. Change ExternalSymbol SDNode to TargetExternalSymbol to avoid legalizer
   split the symbol.

3. Let PseudoCALL match direct call with target operand TargetGlobalAddress
   and TargetExternalSymbol.

Differential Revision: https://reviews.llvm.org/D44885

llvm-svn: 330827
  • Loading branch information
ShivaChen committed Apr 25, 2018
1 parent 98f9389 commit d58bd8d
Show file tree
Hide file tree
Showing 26 changed files with 249 additions and 565 deletions.
11 changes: 7 additions & 4 deletions llvm/lib/Target/RISCV/RISCVISelLowering.cpp
Expand Up @@ -1166,10 +1166,13 @@ SDValue RISCVTargetLowering::LowerCall(CallLoweringInfo &CLI,
Glue = Chain.getValue(1);
}

if (isa<GlobalAddressSDNode>(Callee)) {
Callee = lowerGlobalAddress(Callee, DAG);
} else if (isa<ExternalSymbolSDNode>(Callee)) {
Callee = lowerExternalSymbol(Callee, DAG);
// If the callee is a GlobalAddress/ExternalSymbol node, turn it into a
// TargetGlobalAddress/TargetExternalSymbol node so that legalize won't
// split it and then direct call can be matched by PseudoCALL.
if (GlobalAddressSDNode *S = dyn_cast<GlobalAddressSDNode>(Callee)) {
Callee = DAG.getTargetGlobalAddress(S->getGlobal(), DL, PtrVT, 0, 0);
} else if (ExternalSymbolSDNode *S = dyn_cast<ExternalSymbolSDNode>(Callee)) {
Callee = DAG.getTargetExternalSymbol(S->getSymbol(), PtrVT, 0);
}

// The first call operand is the chain and the second is the target address.
Expand Down
2 changes: 2 additions & 0 deletions llvm/lib/Target/RISCV/RISCVInstrInfo.cpp
Expand Up @@ -387,6 +387,8 @@ unsigned RISCVInstrInfo::getInstSizeInBytes(const MachineInstr &MI) const {
case TargetOpcode::KILL:
case TargetOpcode::DBG_VALUE:
return 0;
case RISCV::PseudoCALL:
return 8;
case TargetOpcode::INLINEASM: {
const MachineFunction &MF = *MI.getParent()->getParent();
const auto &TM = static_cast<const RISCVTargetMachine &>(MF.getTarget());
Expand Down
15 changes: 9 additions & 6 deletions llvm/lib/Target/RISCV/RISCVInstrInfo.td
Expand Up @@ -636,16 +636,19 @@ def : Pat<(brind (add GPR:$rs1, simm12:$imm12)),
(PseudoBRIND GPR:$rs1, simm12:$imm12)>;

// PseudoCALL is a pseudo instruction which will eventually expand to auipc
// and jalr. Define AsmString because we want assembler could print "call"
// when compile with -S. Define isCodeGenOnly = 0 because we want parser
// could parsing assembly "call" instruction.
let isCall = 1, Defs = [X1], isCodeGenOnly = 0,
hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
// and jalr while encoding. This is desirable, as an auipc+jalr pair with
// R_RISCV_CALL and R_RISCV_RELAX relocations can be be relaxed by the linker
// if the offset fits in a signed 21-bit immediate.
// Define AsmString to print "call" when compile with -S flag.
// Define isCodeGenOnly = 0 to support parsing assembly "call" instruction.
let isCall = 1, Defs = [X1], isCodeGenOnly = 0 in
def PseudoCALL : Pseudo<(outs), (ins bare_symbol:$func),
[]> {
[(Call tglobaladdr:$func)]> {
let AsmString = "call\t$func";
}

def : Pat<(Call texternalsym:$func), (PseudoCALL texternalsym:$func)>;

let isCall = 1, Defs = [X1] in
def PseudoCALLIndirect : Pseudo<(outs), (ins GPR:$rs1), [(Call GPR:$rs1)]>,
PseudoInstExpansion<(JALR X1, GPR:$rs1, 0)>;
Expand Down
12 changes: 3 additions & 9 deletions llvm/test/CodeGen/RISCV/alloca.ll
Expand Up @@ -18,9 +18,7 @@ define void @simple_alloca(i32 %n) nounwind {
; RV32I-NEXT: andi a0, a0, -16
; RV32I-NEXT: sub a0, sp, a0
; RV32I-NEXT: mv sp, a0
; RV32I-NEXT: lui a1, %hi(notdead)
; RV32I-NEXT: addi a1, a1, %lo(notdead)
; RV32I-NEXT: jalr a1
; RV32I-NEXT: call notdead
; RV32I-NEXT: addi sp, s0, -16
; RV32I-NEXT: lw s0, 8(sp)
; RV32I-NEXT: lw ra, 12(sp)
Expand All @@ -47,9 +45,7 @@ define void @scoped_alloca(i32 %n) nounwind {
; RV32I-NEXT: andi a0, a0, -16
; RV32I-NEXT: sub a0, sp, a0
; RV32I-NEXT: mv sp, a0
; RV32I-NEXT: lui a1, %hi(notdead)
; RV32I-NEXT: addi a1, a1, %lo(notdead)
; RV32I-NEXT: jalr a1
; RV32I-NEXT: call notdead
; RV32I-NEXT: mv sp, s1
; RV32I-NEXT: addi sp, s0, -16
; RV32I-NEXT: lw s1, 4(sp)
Expand Down Expand Up @@ -88,16 +84,14 @@ define void @alloca_callframe(i32 %n) nounwind {
; RV32I-NEXT: sw a1, 4(sp)
; RV32I-NEXT: addi a1, zero, 9
; RV32I-NEXT: sw a1, 0(sp)
; RV32I-NEXT: lui a1, %hi(func)
; RV32I-NEXT: addi t0, a1, %lo(func)
; RV32I-NEXT: addi a1, zero, 2
; RV32I-NEXT: addi a2, zero, 3
; RV32I-NEXT: addi a3, zero, 4
; RV32I-NEXT: addi a4, zero, 5
; RV32I-NEXT: addi a5, zero, 6
; RV32I-NEXT: addi a6, zero, 7
; RV32I-NEXT: addi a7, zero, 8
; RV32I-NEXT: jalr t0
; RV32I-NEXT: call func
; RV32I-NEXT: addi sp, sp, 16
; RV32I-NEXT: addi sp, s0, -16
; RV32I-NEXT: lw s0, 8(sp)
Expand Down
14 changes: 4 additions & 10 deletions llvm/test/CodeGen/RISCV/analyze-branch.ll
Expand Up @@ -20,16 +20,13 @@ define void @test_bcc_fallthrough_taken(i32 %in) nounwind {
; RV32I-NEXT: addi a1, zero, 42
; RV32I-NEXT: bne a0, a1, .LBB0_3
; RV32I-NEXT: # %bb.1: # %true
; RV32I-NEXT: lui a0, %hi(test_true)
; RV32I-NEXT: addi a0, a0, %lo(test_true)
; RV32I-NEXT: call test_true
; RV32I-NEXT: .LBB0_2: # %true
; RV32I-NEXT: jalr a0
; RV32I-NEXT: lw ra, 12(sp)
; RV32I-NEXT: addi sp, sp, 16
; RV32I-NEXT: ret
; RV32I-NEXT: .LBB0_3: # %false
; RV32I-NEXT: lui a0, %hi(test_false)
; RV32I-NEXT: addi a0, a0, %lo(test_false)
; RV32I-NEXT: call test_false
; RV32I-NEXT: j .LBB0_2
%tst = icmp eq i32 %in, 42
br i1 %tst, label %true, label %false, !prof !0
Expand All @@ -55,16 +52,13 @@ define void @test_bcc_fallthrough_nottaken(i32 %in) nounwind {
; RV32I-NEXT: addi a1, zero, 42
; RV32I-NEXT: beq a0, a1, .LBB1_3
; RV32I-NEXT: # %bb.1: # %false
; RV32I-NEXT: lui a0, %hi(test_false)
; RV32I-NEXT: addi a0, a0, %lo(test_false)
; RV32I-NEXT: call test_false
; RV32I-NEXT: .LBB1_2: # %true
; RV32I-NEXT: jalr a0
; RV32I-NEXT: lw ra, 12(sp)
; RV32I-NEXT: addi sp, sp, 16
; RV32I-NEXT: ret
; RV32I-NEXT: .LBB1_3: # %true
; RV32I-NEXT: lui a0, %hi(test_true)
; RV32I-NEXT: addi a0, a0, %lo(test_true)
; RV32I-NEXT: call test_true
; RV32I-NEXT: j .LBB1_2
%tst = icmp eq i32 %in, 42
br i1 %tst, label %true, label %false, !prof !1
Expand Down
132 changes: 54 additions & 78 deletions llvm/test/CodeGen/RISCV/bswap-ctlz-cttz-ctpop.ll
Expand Up @@ -105,9 +105,7 @@ define i8 @test_cttz_i8(i8 %a) nounwind {
; RV32I-NEXT: and a0, a0, a1
; RV32I-NEXT: lui a1, 4112
; RV32I-NEXT: addi a1, a1, 257
; RV32I-NEXT: lui a2, %hi(__mulsi3)
; RV32I-NEXT: addi a2, a2, %lo(__mulsi3)
; RV32I-NEXT: jalr a2
; RV32I-NEXT: call __mulsi3
; RV32I-NEXT: srli a0, a0, 24
; RV32I-NEXT: j .LBB3_3
; RV32I-NEXT: .LBB3_2:
Expand Down Expand Up @@ -151,9 +149,7 @@ define i16 @test_cttz_i16(i16 %a) nounwind {
; RV32I-NEXT: and a0, a0, a1
; RV32I-NEXT: lui a1, 4112
; RV32I-NEXT: addi a1, a1, 257
; RV32I-NEXT: lui a2, %hi(__mulsi3)
; RV32I-NEXT: addi a2, a2, %lo(__mulsi3)
; RV32I-NEXT: jalr a2
; RV32I-NEXT: call __mulsi3
; RV32I-NEXT: srli a0, a0, 24
; RV32I-NEXT: j .LBB4_3
; RV32I-NEXT: .LBB4_2:
Expand Down Expand Up @@ -194,9 +190,7 @@ define i32 @test_cttz_i32(i32 %a) nounwind {
; RV32I-NEXT: and a0, a0, a1
; RV32I-NEXT: lui a1, 4112
; RV32I-NEXT: addi a1, a1, 257
; RV32I-NEXT: lui a2, %hi(__mulsi3)
; RV32I-NEXT: addi a2, a2, %lo(__mulsi3)
; RV32I-NEXT: jalr a2
; RV32I-NEXT: call __mulsi3
; RV32I-NEXT: srli a0, a0, 24
; RV32I-NEXT: j .LBB5_3
; RV32I-NEXT: .LBB5_2:
Expand Down Expand Up @@ -245,9 +239,7 @@ define i32 @test_ctlz_i32(i32 %a) nounwind {
; RV32I-NEXT: and a0, a0, a1
; RV32I-NEXT: lui a1, 4112
; RV32I-NEXT: addi a1, a1, 257
; RV32I-NEXT: lui a2, %hi(__mulsi3)
; RV32I-NEXT: addi a2, a2, %lo(__mulsi3)
; RV32I-NEXT: jalr a2
; RV32I-NEXT: call __mulsi3
; RV32I-NEXT: srli a0, a0, 24
; RV32I-NEXT: j .LBB6_3
; RV32I-NEXT: .LBB6_2:
Expand All @@ -263,16 +255,15 @@ define i32 @test_ctlz_i32(i32 %a) nounwind {
define i64 @test_cttz_i64(i64 %a) nounwind {
; RV32I-LABEL: test_cttz_i64:
; RV32I: # %bb.0:
; RV32I-NEXT: addi sp, sp, -48
; RV32I-NEXT: sw ra, 44(sp)
; RV32I-NEXT: sw s1, 40(sp)
; RV32I-NEXT: sw s2, 36(sp)
; RV32I-NEXT: sw s3, 32(sp)
; RV32I-NEXT: sw s4, 28(sp)
; RV32I-NEXT: sw s5, 24(sp)
; RV32I-NEXT: sw s6, 20(sp)
; RV32I-NEXT: sw s7, 16(sp)
; RV32I-NEXT: sw s8, 12(sp)
; RV32I-NEXT: addi sp, sp, -32
; 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: mv s2, a1
; RV32I-NEXT: mv s3, a0
; RV32I-NEXT: addi a0, a0, -1
Expand All @@ -293,13 +284,11 @@ define i64 @test_cttz_i64(i64 %a) nounwind {
; RV32I-NEXT: add a0, a0, a1
; RV32I-NEXT: lui a1, 4112
; RV32I-NEXT: addi s4, a1, 257
; RV32I-NEXT: lui a1, %hi(__mulsi3)
; RV32I-NEXT: addi s7, a1, %lo(__mulsi3)
; RV32I-NEXT: lui a1, 61681
; RV32I-NEXT: addi s8, a1, -241
; RV32I-NEXT: and a0, a0, s8
; RV32I-NEXT: addi s7, a1, -241
; RV32I-NEXT: and a0, a0, s7
; RV32I-NEXT: mv a1, s4
; RV32I-NEXT: jalr s7
; RV32I-NEXT: call __mulsi3
; RV32I-NEXT: mv s1, a0
; RV32I-NEXT: addi a0, s2, -1
; RV32I-NEXT: not a1, s2
Expand All @@ -313,9 +302,9 @@ define i64 @test_cttz_i64(i64 %a) nounwind {
; RV32I-NEXT: add a0, a1, a0
; RV32I-NEXT: srli a1, a0, 4
; RV32I-NEXT: add a0, a0, a1
; RV32I-NEXT: and a0, a0, s8
; RV32I-NEXT: and a0, a0, s7
; RV32I-NEXT: mv a1, s4
; RV32I-NEXT: jalr s7
; RV32I-NEXT: call __mulsi3
; RV32I-NEXT: bnez s3, .LBB7_2
; RV32I-NEXT: # %bb.1:
; RV32I-NEXT: srli a0, a0, 24
Expand All @@ -325,16 +314,15 @@ define i64 @test_cttz_i64(i64 %a) nounwind {
; RV32I-NEXT: srli a0, s1, 24
; RV32I-NEXT: .LBB7_3:
; RV32I-NEXT: mv a1, zero
; RV32I-NEXT: lw s8, 12(sp)
; RV32I-NEXT: lw s7, 16(sp)
; RV32I-NEXT: lw s6, 20(sp)
; RV32I-NEXT: lw s5, 24(sp)
; RV32I-NEXT: lw s4, 28(sp)
; RV32I-NEXT: lw s3, 32(sp)
; RV32I-NEXT: lw s2, 36(sp)
; RV32I-NEXT: lw s1, 40(sp)
; RV32I-NEXT: lw ra, 44(sp)
; RV32I-NEXT: addi sp, sp, 48
; 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: addi sp, sp, 32
; RV32I-NEXT: ret
%tmp = call i64 @llvm.cttz.i64(i64 %a, i1 false)
ret i64 %tmp
Expand Down Expand Up @@ -366,9 +354,7 @@ define i8 @test_cttz_i8_zero_undef(i8 %a) nounwind {
; RV32I-NEXT: and a0, a0, a1
; RV32I-NEXT: lui a1, 4112
; RV32I-NEXT: addi a1, a1, 257
; RV32I-NEXT: lui a2, %hi(__mulsi3)
; RV32I-NEXT: addi a2, a2, %lo(__mulsi3)
; RV32I-NEXT: jalr a2
; RV32I-NEXT: call __mulsi3
; RV32I-NEXT: srli a0, a0, 24
; RV32I-NEXT: lw ra, 12(sp)
; RV32I-NEXT: addi sp, sp, 16
Expand Down Expand Up @@ -403,9 +389,7 @@ define i16 @test_cttz_i16_zero_undef(i16 %a) nounwind {
; RV32I-NEXT: and a0, a0, a1
; RV32I-NEXT: lui a1, 4112
; RV32I-NEXT: addi a1, a1, 257
; RV32I-NEXT: lui a2, %hi(__mulsi3)
; RV32I-NEXT: addi a2, a2, %lo(__mulsi3)
; RV32I-NEXT: jalr a2
; RV32I-NEXT: call __mulsi3
; RV32I-NEXT: srli a0, a0, 24
; RV32I-NEXT: lw ra, 12(sp)
; RV32I-NEXT: addi sp, sp, 16
Expand Down Expand Up @@ -440,9 +424,7 @@ define i32 @test_cttz_i32_zero_undef(i32 %a) nounwind {
; RV32I-NEXT: and a0, a0, a1
; RV32I-NEXT: lui a1, 4112
; RV32I-NEXT: addi a1, a1, 257
; RV32I-NEXT: lui a2, %hi(__mulsi3)
; RV32I-NEXT: addi a2, a2, %lo(__mulsi3)
; RV32I-NEXT: jalr a2
; RV32I-NEXT: call __mulsi3
; RV32I-NEXT: srli a0, a0, 24
; RV32I-NEXT: lw ra, 12(sp)
; RV32I-NEXT: addi sp, sp, 16
Expand All @@ -454,16 +436,15 @@ define i32 @test_cttz_i32_zero_undef(i32 %a) nounwind {
define i64 @test_cttz_i64_zero_undef(i64 %a) nounwind {
; RV32I-LABEL: test_cttz_i64_zero_undef:
; RV32I: # %bb.0:
; RV32I-NEXT: addi sp, sp, -48
; RV32I-NEXT: sw ra, 44(sp)
; RV32I-NEXT: sw s1, 40(sp)
; RV32I-NEXT: sw s2, 36(sp)
; RV32I-NEXT: sw s3, 32(sp)
; RV32I-NEXT: sw s4, 28(sp)
; RV32I-NEXT: sw s5, 24(sp)
; RV32I-NEXT: sw s6, 20(sp)
; RV32I-NEXT: sw s7, 16(sp)
; RV32I-NEXT: sw s8, 12(sp)
; RV32I-NEXT: addi sp, sp, -32
; 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: mv s2, a1
; RV32I-NEXT: mv s3, a0
; RV32I-NEXT: addi a0, a0, -1
Expand All @@ -484,13 +465,11 @@ define i64 @test_cttz_i64_zero_undef(i64 %a) nounwind {
; RV32I-NEXT: add a0, a0, a1
; RV32I-NEXT: lui a1, 4112
; RV32I-NEXT: addi s4, a1, 257
; RV32I-NEXT: lui a1, %hi(__mulsi3)
; RV32I-NEXT: addi s7, a1, %lo(__mulsi3)
; RV32I-NEXT: lui a1, 61681
; RV32I-NEXT: addi s8, a1, -241
; RV32I-NEXT: and a0, a0, s8
; RV32I-NEXT: addi s7, a1, -241
; RV32I-NEXT: and a0, a0, s7
; RV32I-NEXT: mv a1, s4
; RV32I-NEXT: jalr s7
; RV32I-NEXT: call __mulsi3
; RV32I-NEXT: mv s1, a0
; RV32I-NEXT: addi a0, s2, -1
; RV32I-NEXT: not a1, s2
Expand All @@ -504,9 +483,9 @@ define i64 @test_cttz_i64_zero_undef(i64 %a) nounwind {
; RV32I-NEXT: add a0, a1, a0
; RV32I-NEXT: srli a1, a0, 4
; RV32I-NEXT: add a0, a0, a1
; RV32I-NEXT: and a0, a0, s8
; RV32I-NEXT: and a0, a0, s7
; RV32I-NEXT: mv a1, s4
; RV32I-NEXT: jalr s7
; RV32I-NEXT: call __mulsi3
; RV32I-NEXT: bnez s3, .LBB11_2
; RV32I-NEXT: # %bb.1:
; RV32I-NEXT: srli a0, a0, 24
Expand All @@ -516,16 +495,15 @@ define i64 @test_cttz_i64_zero_undef(i64 %a) nounwind {
; RV32I-NEXT: srli a0, s1, 24
; RV32I-NEXT: .LBB11_3:
; RV32I-NEXT: mv a1, zero
; RV32I-NEXT: lw s8, 12(sp)
; RV32I-NEXT: lw s7, 16(sp)
; RV32I-NEXT: lw s6, 20(sp)
; RV32I-NEXT: lw s5, 24(sp)
; RV32I-NEXT: lw s4, 28(sp)
; RV32I-NEXT: lw s3, 32(sp)
; RV32I-NEXT: lw s2, 36(sp)
; RV32I-NEXT: lw s1, 40(sp)
; RV32I-NEXT: lw ra, 44(sp)
; RV32I-NEXT: addi sp, sp, 48
; 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: addi sp, sp, 32
; RV32I-NEXT: ret
%tmp = call i64 @llvm.cttz.i64(i64 %a, i1 true)
ret i64 %tmp
Expand Down Expand Up @@ -554,9 +532,7 @@ define i32 @test_ctpop_i32(i32 %a) nounwind {
; RV32I-NEXT: and a0, a0, a1
; RV32I-NEXT: lui a1, 4112
; RV32I-NEXT: addi a1, a1, 257
; RV32I-NEXT: lui a2, %hi(__mulsi3)
; RV32I-NEXT: addi a2, a2, %lo(__mulsi3)
; RV32I-NEXT: jalr a2
; RV32I-NEXT: call __mulsi3
; RV32I-NEXT: srli a0, a0, 24
; RV32I-NEXT: lw ra, 12(sp)
; RV32I-NEXT: addi sp, sp, 16
Expand Down
4 changes: 1 addition & 3 deletions llvm/test/CodeGen/RISCV/byval.ll
Expand Up @@ -34,10 +34,8 @@ define void @caller() nounwind {
; RV32I-NEXT: lui a0, %hi(foo)
; RV32I-NEXT: lw a0, %lo(foo)(a0)
; RV32I-NEXT: sw a0, 12(sp)
; RV32I-NEXT: lui a0, %hi(callee)
; RV32I-NEXT: addi a1, a0, %lo(callee)
; RV32I-NEXT: addi a0, sp, 12
; RV32I-NEXT: jalr a1
; RV32I-NEXT: call callee
; RV32I-NEXT: lw ra, 28(sp)
; RV32I-NEXT: addi sp, sp, 32
; RV32I-NEXT: ret
Expand Down

0 comments on commit d58bd8d

Please sign in to comment.