[llvm] r363686 - [RISCV] Lower calls through PLT

Lewis Revill via llvm-commits llvm-commits at lists.llvm.org
Tue Jun 18 07:29:45 PDT 2019


Author: lewis-revill
Date: Tue Jun 18 07:29:45 2019
New Revision: 363686

URL: http://llvm.org/viewvc/llvm-project?rev=363686&view=rev
Log:
[RISCV] Lower calls through PLT

This patch adds support for generating calls through the procedure
linkage table where required for a given ExternalSymbol or GlobalAddress
callee.

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

Modified:
    llvm/trunk/lib/Target/RISCV/RISCVISelLowering.cpp
    llvm/trunk/lib/Target/RISCV/RISCVMCInstLower.cpp
    llvm/trunk/lib/Target/RISCV/Utils/RISCVBaseInfo.h
    llvm/trunk/test/CodeGen/RISCV/calls.ll

Modified: llvm/trunk/lib/Target/RISCV/RISCVISelLowering.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/RISCV/RISCVISelLowering.cpp?rev=363686&r1=363685&r2=363686&view=diff
==============================================================================
--- llvm/trunk/lib/Target/RISCV/RISCVISelLowering.cpp (original)
+++ llvm/trunk/lib/Target/RISCV/RISCVISelLowering.cpp Tue Jun 18 07:29:45 2019
@@ -1921,11 +1921,21 @@ SDValue RISCVTargetLowering::LowerCall(C
   // 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,
-                                        RISCVII::MO_CALL);
+    const GlobalValue *GV = S->getGlobal();
+
+    unsigned OpFlags = RISCVII::MO_CALL;
+    if (!getTargetMachine().shouldAssumeDSOLocal(*GV->getParent(), GV))
+      OpFlags = RISCVII::MO_PLT;
+
+    Callee = DAG.getTargetGlobalAddress(GV, DL, PtrVT, 0, OpFlags);
   } else if (ExternalSymbolSDNode *S = dyn_cast<ExternalSymbolSDNode>(Callee)) {
-    Callee =
-        DAG.getTargetExternalSymbol(S->getSymbol(), PtrVT, RISCVII::MO_CALL);
+    unsigned OpFlags = RISCVII::MO_CALL;
+
+    if (!getTargetMachine().shouldAssumeDSOLocal(*MF.getFunction().getParent(),
+                                                 nullptr))
+      OpFlags = RISCVII::MO_PLT;
+
+    Callee = DAG.getTargetExternalSymbol(S->getSymbol(), PtrVT, OpFlags);
   }
 
   // The first call operand is the chain and the second is the target address.

Modified: llvm/trunk/lib/Target/RISCV/RISCVMCInstLower.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/RISCV/RISCVMCInstLower.cpp?rev=363686&r1=363685&r2=363686&view=diff
==============================================================================
--- llvm/trunk/lib/Target/RISCV/RISCVMCInstLower.cpp (original)
+++ llvm/trunk/lib/Target/RISCV/RISCVMCInstLower.cpp Tue Jun 18 07:29:45 2019
@@ -39,6 +39,9 @@ static MCOperand lowerSymbolOperand(cons
   case RISCVII::MO_CALL:
     Kind = RISCVMCExpr::VK_RISCV_CALL;
     break;
+  case RISCVII::MO_PLT:
+    Kind = RISCVMCExpr::VK_RISCV_CALL_PLT;
+    break;
   case RISCVII::MO_LO:
     Kind = RISCVMCExpr::VK_RISCV_LO;
     break;

Modified: llvm/trunk/lib/Target/RISCV/Utils/RISCVBaseInfo.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/RISCV/Utils/RISCVBaseInfo.h?rev=363686&r1=363685&r2=363686&view=diff
==============================================================================
--- llvm/trunk/lib/Target/RISCV/Utils/RISCVBaseInfo.h (original)
+++ llvm/trunk/lib/Target/RISCV/Utils/RISCVBaseInfo.h Tue Jun 18 07:29:45 2019
@@ -49,6 +49,7 @@ enum {
 enum {
   MO_None,
   MO_CALL,
+  MO_PLT,
   MO_LO,
   MO_HI,
   MO_PCREL_LO,

Modified: llvm/trunk/test/CodeGen/RISCV/calls.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/RISCV/calls.ll?rev=363686&r1=363685&r2=363686&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/RISCV/calls.ll (original)
+++ llvm/trunk/test/CodeGen/RISCV/calls.ll Tue Jun 18 07:29:45 2019
@@ -1,6 +1,8 @@
 ; 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
+; RUN: llc -relocation-model=pic -mtriple=riscv32 -verify-machineinstrs < %s \
+; RUN:   | FileCheck -check-prefix=RV32I-PIC %s
 
 declare i32 @external_function(i32)
 
@@ -13,15 +15,53 @@ define i32 @test_call_external(i32 %a) n
 ; RV32I-NEXT:    lw ra, 12(sp)
 ; RV32I-NEXT:    addi sp, sp, 16
 ; RV32I-NEXT:    ret
+;
+; RV32I-PIC-LABEL: test_call_external:
+; RV32I-PIC:       # %bb.0:
+; RV32I-PIC-NEXT:    addi sp, sp, -16
+; RV32I-PIC-NEXT:    sw ra, 12(sp)
+; RV32I-PIC-NEXT:    call external_function at plt
+; RV32I-PIC-NEXT:    lw ra, 12(sp)
+; RV32I-PIC-NEXT:    addi sp, sp, 16
+; RV32I-PIC-NEXT:    ret
   %1 = call i32 @external_function(i32 %a)
   ret i32 %1
 }
 
+declare dso_local i32 @dso_local_function(i32)
+
+define i32 @test_call_dso_local(i32 %a) nounwind {
+; RV32I-LABEL: test_call_dso_local:
+; RV32I:       # %bb.0:
+; RV32I-NEXT:    addi sp, sp, -16
+; RV32I-NEXT:    sw ra, 12(sp)
+; RV32I-NEXT:    call dso_local_function
+; RV32I-NEXT:    lw ra, 12(sp)
+; RV32I-NEXT:    addi sp, sp, 16
+; RV32I-NEXT:    ret
+;
+; RV32I-PIC-LABEL: test_call_dso_local:
+; RV32I-PIC:       # %bb.0:
+; RV32I-PIC-NEXT:    addi sp, sp, -16
+; RV32I-PIC-NEXT:    sw ra, 12(sp)
+; RV32I-PIC-NEXT:    call dso_local_function
+; RV32I-PIC-NEXT:    lw ra, 12(sp)
+; RV32I-PIC-NEXT:    addi sp, sp, 16
+; RV32I-PIC-NEXT:    ret
+  %1 = call i32 @dso_local_function(i32 %a)
+  ret i32 %1
+}
+
 define i32 @defined_function(i32 %a) nounwind {
 ; RV32I-LABEL: defined_function:
 ; RV32I:       # %bb.0:
 ; RV32I-NEXT:    addi a0, a0, 1
 ; RV32I-NEXT:    ret
+;
+; RV32I-PIC-LABEL: defined_function:
+; RV32I-PIC:       # %bb.0:
+; RV32I-PIC-NEXT:    addi a0, a0, 1
+; RV32I-PIC-NEXT:    ret
   %1 = add i32 %a, 1
   ret i32 %1
 }
@@ -35,6 +75,15 @@ define i32 @test_call_defined(i32 %a) no
 ; RV32I-NEXT:    lw ra, 12(sp)
 ; RV32I-NEXT:    addi sp, sp, 16
 ; RV32I-NEXT:    ret
+;
+; RV32I-PIC-LABEL: test_call_defined:
+; RV32I-PIC:       # %bb.0:
+; RV32I-PIC-NEXT:    addi sp, sp, -16
+; RV32I-PIC-NEXT:    sw ra, 12(sp)
+; RV32I-PIC-NEXT:    call defined_function at plt
+; RV32I-PIC-NEXT:    lw ra, 12(sp)
+; RV32I-PIC-NEXT:    addi sp, sp, 16
+; RV32I-PIC-NEXT:    ret
   %1 = call i32 @defined_function(i32 %a)
   ret i32 %1
 }
@@ -50,6 +99,17 @@ define i32 @test_call_indirect(i32 (i32)
 ; RV32I-NEXT:    lw ra, 12(sp)
 ; RV32I-NEXT:    addi sp, sp, 16
 ; RV32I-NEXT:    ret
+;
+; RV32I-PIC-LABEL: test_call_indirect:
+; RV32I-PIC:       # %bb.0:
+; RV32I-PIC-NEXT:    addi sp, sp, -16
+; RV32I-PIC-NEXT:    sw ra, 12(sp)
+; RV32I-PIC-NEXT:    mv a2, a0
+; RV32I-PIC-NEXT:    mv a0, a1
+; RV32I-PIC-NEXT:    jalr a2
+; RV32I-PIC-NEXT:    lw ra, 12(sp)
+; RV32I-PIC-NEXT:    addi sp, sp, 16
+; RV32I-PIC-NEXT:    ret
   %1 = call i32 %a(i32 %b)
   ret i32 %1
 }
@@ -62,6 +122,11 @@ define fastcc i32 @fastcc_function(i32 %
 ; RV32I:       # %bb.0:
 ; RV32I-NEXT:    add a0, a0, a1
 ; RV32I-NEXT:    ret
+;
+; RV32I-PIC-LABEL: fastcc_function:
+; RV32I-PIC:       # %bb.0:
+; RV32I-PIC-NEXT:    add a0, a0, a1
+; RV32I-PIC-NEXT:    ret
  %1 = add i32 %a, %b
  ret i32 %1
 }
@@ -79,6 +144,19 @@ define i32 @test_call_fastcc(i32 %a, i32
 ; RV32I-NEXT:    lw ra, 12(sp)
 ; RV32I-NEXT:    addi sp, sp, 16
 ; RV32I-NEXT:    ret
+;
+; RV32I-PIC-LABEL: test_call_fastcc:
+; RV32I-PIC:       # %bb.0:
+; RV32I-PIC-NEXT:    addi sp, sp, -16
+; RV32I-PIC-NEXT:    sw ra, 12(sp)
+; RV32I-PIC-NEXT:    sw s0, 8(sp)
+; RV32I-PIC-NEXT:    mv s0, a0
+; RV32I-PIC-NEXT:    call fastcc_function at plt
+; RV32I-PIC-NEXT:    mv a0, s0
+; RV32I-PIC-NEXT:    lw s0, 8(sp)
+; RV32I-PIC-NEXT:    lw ra, 12(sp)
+; RV32I-PIC-NEXT:    addi sp, sp, 16
+; RV32I-PIC-NEXT:    ret
   %1 = call fastcc i32 @fastcc_function(i32 %a, i32 %b)
   ret i32 %a
 }
@@ -107,6 +185,28 @@ define i32 @test_call_external_many_args
 ; RV32I-NEXT:    lw ra, 12(sp)
 ; RV32I-NEXT:    addi sp, sp, 16
 ; RV32I-NEXT:    ret
+;
+; RV32I-PIC-LABEL: test_call_external_many_args:
+; RV32I-PIC:       # %bb.0:
+; RV32I-PIC-NEXT:    addi sp, sp, -16
+; RV32I-PIC-NEXT:    sw ra, 12(sp)
+; RV32I-PIC-NEXT:    sw s0, 8(sp)
+; RV32I-PIC-NEXT:    mv s0, a0
+; RV32I-PIC-NEXT:    sw a0, 4(sp)
+; RV32I-PIC-NEXT:    sw a0, 0(sp)
+; RV32I-PIC-NEXT:    mv a1, a0
+; RV32I-PIC-NEXT:    mv a2, a0
+; RV32I-PIC-NEXT:    mv a3, a0
+; RV32I-PIC-NEXT:    mv a4, a0
+; RV32I-PIC-NEXT:    mv a5, a0
+; RV32I-PIC-NEXT:    mv a6, a0
+; RV32I-PIC-NEXT:    mv a7, a0
+; RV32I-PIC-NEXT:    call external_many_args at plt
+; RV32I-PIC-NEXT:    mv a0, s0
+; RV32I-PIC-NEXT:    lw s0, 8(sp)
+; RV32I-PIC-NEXT:    lw ra, 12(sp)
+; RV32I-PIC-NEXT:    addi sp, sp, 16
+; RV32I-PIC-NEXT:    ret
   %1 = call i32 @external_many_args(i32 %a, i32 %a, i32 %a, i32 %a, i32 %a,
                                     i32 %a, i32 %a, i32 %a, i32 %a, i32 %a)
   ret i32 %a
@@ -118,6 +218,12 @@ define i32 @defined_many_args(i32, i32,
 ; RV32I-NEXT:    lw a0, 4(sp)
 ; RV32I-NEXT:    addi a0, a0, 1
 ; RV32I-NEXT:    ret
+;
+; RV32I-PIC-LABEL: defined_many_args:
+; RV32I-PIC:       # %bb.0:
+; RV32I-PIC-NEXT:    lw a0, 4(sp)
+; RV32I-PIC-NEXT:    addi a0, a0, 1
+; RV32I-PIC-NEXT:    ret
   %added = add i32 %j, 1
   ret i32 %added
 }
@@ -140,6 +246,24 @@ define i32 @test_call_defined_many_args(
 ; RV32I-NEXT:    lw ra, 12(sp)
 ; RV32I-NEXT:    addi sp, sp, 16
 ; RV32I-NEXT:    ret
+;
+; RV32I-PIC-LABEL: test_call_defined_many_args:
+; RV32I-PIC:       # %bb.0:
+; RV32I-PIC-NEXT:    addi sp, sp, -16
+; RV32I-PIC-NEXT:    sw ra, 12(sp)
+; RV32I-PIC-NEXT:    sw a0, 4(sp)
+; RV32I-PIC-NEXT:    sw a0, 0(sp)
+; RV32I-PIC-NEXT:    mv a1, a0
+; RV32I-PIC-NEXT:    mv a2, a0
+; RV32I-PIC-NEXT:    mv a3, a0
+; RV32I-PIC-NEXT:    mv a4, a0
+; RV32I-PIC-NEXT:    mv a5, a0
+; RV32I-PIC-NEXT:    mv a6, a0
+; RV32I-PIC-NEXT:    mv a7, a0
+; RV32I-PIC-NEXT:    call defined_many_args at plt
+; RV32I-PIC-NEXT:    lw ra, 12(sp)
+; RV32I-PIC-NEXT:    addi sp, sp, 16
+; RV32I-PIC-NEXT:    ret
   %1 = call i32 @defined_many_args(i32 %a, i32 %a, i32 %a, i32 %a, i32 %a,
                                    i32 %a, i32 %a, i32 %a, i32 %a, i32 %a)
   ret i32 %1




More information about the llvm-commits mailing list