[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