[llvm] 075a92d - [PowerPC] Do not use FISel for calls and TOC-based accesses with PC-Rel

Nemanja Ivanovic via llvm-commits llvm-commits at lists.llvm.org
Mon Aug 24 14:52:10 PDT 2020


Author: Nemanja Ivanovic
Date: 2020-08-24T16:51:44-05:00
New Revision: 075a92dea11ece9e7b7e24238fa995a42b2128d0

URL: https://github.com/llvm/llvm-project/commit/075a92dea11ece9e7b7e24238fa995a42b2128d0
DIFF: https://github.com/llvm/llvm-project/commit/075a92dea11ece9e7b7e24238fa995a42b2128d0.diff

LOG: [PowerPC] Do not use FISel for calls and TOC-based accesses with PC-Rel

PC-Relative addressing introduces a fair bit of complexity for correctly
eliminating TOC accesses. FastISel does not include any of that handling so we
miscompile code with -mcpu=pwr10 -O0 if it includes an external call that
FastISel does not handle followed by any of the following:

    Floating point constant materialization
    Materialization of a GlobalValue
    Call that FastISel does handle

This patch switches to SDISel for any of the above.

Differential revision: https://reviews.llvm.org/D86343

Added: 
    

Modified: 
    llvm/lib/Target/PowerPC/PPCFastISel.cpp
    llvm/test/CodeGen/PowerPC/fast-isel-pcrel.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Target/PowerPC/PPCFastISel.cpp b/llvm/lib/Target/PowerPC/PPCFastISel.cpp
index 39790ac9a8aa..9edbf5f68f32 100644
--- a/llvm/lib/Target/PowerPC/PPCFastISel.cpp
+++ b/llvm/lib/Target/PowerPC/PPCFastISel.cpp
@@ -1567,6 +1567,10 @@ bool PPCFastISel::fastLowerCall(CallLoweringInfo &CLI) {
   if (IsVarArg)
     return false;
 
+  // If this is a PC-Rel function, let SDISel handle the call.
+  if (Subtarget->isUsingPCRelativeCalls())
+    return false;
+
   // Handle simple calls for now, with legal return types and
   // those that can be extended.
   Type *RetTy = CLI.RetTy;
@@ -1991,6 +1995,10 @@ bool PPCFastISel::fastSelectInstruction(const Instruction *I) {
 // Materialize a floating-point constant into a register, and return
 // the register number (or zero if we failed to handle it).
 unsigned PPCFastISel::PPCMaterializeFP(const ConstantFP *CFP, MVT VT) {
+  // If this is a PC-Rel function, let SDISel handle constant pool.
+  if (Subtarget->isUsingPCRelativeCalls())
+    return false;
+
   // No plans to handle long double here.
   if (VT != MVT::f32 && VT != MVT::f64)
     return 0;
@@ -2055,6 +2063,10 @@ unsigned PPCFastISel::PPCMaterializeFP(const ConstantFP *CFP, MVT VT) {
 // Materialize the address of a global value into a register, and return
 // the register number (or zero if we failed to handle it).
 unsigned PPCFastISel::PPCMaterializeGV(const GlobalValue *GV, MVT VT) {
+  // If this is a PC-Rel function, let SDISel handle GV materialization.
+  if (Subtarget->isUsingPCRelativeCalls())
+    return false;
+
   assert(VT == MVT::i64 && "Non-address!");
   const TargetRegisterClass *RC = &PPC::G8RC_and_G8RC_NOX0RegClass;
   unsigned DestReg = createResultReg(RC);

diff  --git a/llvm/test/CodeGen/PowerPC/fast-isel-pcrel.ll b/llvm/test/CodeGen/PowerPC/fast-isel-pcrel.ll
index 13fa8a8119bf..3758f8db10ce 100644
--- a/llvm/test/CodeGen/PowerPC/fast-isel-pcrel.ll
+++ b/llvm/test/CodeGen/PowerPC/fast-isel-pcrel.ll
@@ -13,17 +13,21 @@
 ; Function Attrs: noinline nounwind optnone
 define internal void @loadFP(double* %d) #0 {
 ; CHECK-LABEL: loadFP:
-; CHECK:       # %bb.0: # %entry
+; CHECK:         .localentry loadFP, 1
+; CHECK-NEXT:  # %bb.0: # %entry
 ; CHECK-NEXT:    mflr r0
 ; CHECK-NEXT:    std r0, 16(r1)
 ; CHECK-NEXT:    stdu r1, -112(r1)
 ; CHECK-NEXT:    std r3, 104(r1)
 ; CHECK-NEXT:    paddi r3, 0, .L.str at PCREL, 1
 ; CHECK-NEXT:    bl printf at notoc
-; CHECK-NEXT:    addis r4, r2, .LCPI0_0 at toc@ha
-; CHECK-NEXT:    lfd f0, .LCPI0_0 at toc@l(r4)
 ; CHECK-NEXT:    ld r4, 104(r1)
-; CHECK-NEXT:    stfd f0, 0(r4)
+; CHECK-NEXT:    lis r5, 16403
+; CHECK-NEXT:    ori r5, r5, 62914
+; CHECK-NEXT:    sldi r5, r5, 32
+; CHECK-NEXT:    oris r5, r5, 36700
+; CHECK-NEXT:    ori r5, r5, 10486
+; CHECK-NEXT:    std r5, 0(r4)
 ; CHECK-NEXT:    addi r1, r1, 112
 ; CHECK-NEXT:    ld r0, 16(r1)
 ; CHECK-NEXT:    mtlr r0
@@ -42,21 +46,19 @@ declare signext i32 @printf(i8*, ...)
 ; Function Attrs: noinline nounwind optnone
 define internal void @loadGV() #0 {
 ; CHECK-LABEL: loadGV:
-; CHECK:       # %bb.0: # %entry
+; CHECK:         .localentry loadGV, 1
+; CHECK-NEXT:  # %bb.0: # %entry
 ; CHECK-NEXT:    mflr r0
 ; CHECK-NEXT:    std r0, 16(r1)
 ; CHECK-NEXT:    stdu r1, -112(r1)
 ; CHECK-NEXT:    paddi r3, 0, .L.str.1 at PCREL, 1
 ; CHECK-NEXT:    bl printf at notoc
-; CHECK-NEXT:    addis r4, r2, .LC0 at toc@ha
-; CHECK-NEXT:    ld r4, .LC0 at toc@l(r4)
+; CHECK-NEXT:    pld r4, stdout at got@pcrel(0), 1
 ; CHECK-NEXT:    ld r4, 0(r4)
 ; CHECK-NEXT:    li r5, 97
-; CHECK-NEXT:    extsw r5, r5
 ; CHECK-NEXT:    std r3, 104(r1) # 8-byte Folded Spill
 ; CHECK-NEXT:    mr r3, r5
-; CHECK-NEXT:    bl _IO_putc
-; CHECK-NEXT:    nop
+; CHECK-NEXT:    bl _IO_putc at notoc
 ; CHECK-NEXT:    addi r1, r1, 112
 ; CHECK-NEXT:    ld r0, 16(r1)
 ; CHECK-NEXT:    mtlr r0


        


More information about the llvm-commits mailing list