[PATCH] D69534: [X86] Lower frame references with large offsets
David Greene via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Tue Oct 29 14:33:48 PDT 2019
greened updated this revision to Diff 226971.
greened added a comment.
This revision avoids the more general use of register scavenging, opting instead for a local register scavenger which can operate in backward mode, which doesn't need up-to-date liveness information. This seems safer to me, avoiding lots of potentially unknown pitfalls in the X86 backend.
I am not sure whether the `FIXME` actually applies. If the scavenger is guaranteed to return a stack slot with a small offset, then we can lift the spilling restriction.
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D69534/new/
https://reviews.llvm.org/D69534
Files:
llvm/lib/Target/X86/X86RegisterInfo.cpp
llvm/test/CodeGen/X86/large-stack-offset.ll
Index: llvm/test/CodeGen/X86/large-stack-offset.ll
===================================================================
--- /dev/null
+++ llvm/test/CodeGen/X86/large-stack-offset.ll
@@ -0,0 +1,34 @@
+; Test that we can support a large immediate offset on the stack.
+;
+; RUN: llc %s -o - | FileCheck %s
+;
+; ModuleID = 'bugpoint-reduced-simplified.bc'
+source_filename = "test.c"
+target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+ at .str.7 = external dso_local unnamed_addr constant [73 x i8], align 1
+
+; Function Attrs: noinline optnone
+define dso_local void @main() local_unnamed_addr #0 {
+entry:
+ %result = alloca [1048576000 x double], align 16
+ br i1 undef, label %if.then, label %if.end
+
+if.then: ; preds = %entry
+ unreachable
+
+if.end: ; preds = %entry
+ %arrayidx34 = getelementptr inbounds [1048576000 x double], [1048576000 x double]* %result, i64 0, i64 262143999
+; CHECK: movabsq{{[[:space:]]+}}$2298478584,{{[[:space:]]+}}[[INDEX:%[a-z]+]]{{[[:space:]]+}}# imm = 0x88FFFFF8
+; CHECK-NEXT: movsd{{[[:space:]]+}}(%rbp,[[INDEX]]),{{[[:space:]]+}}{{%[a-z0-9]+}}
+
+ %0 = load double, double* %arrayidx34, align 8
+ call void (i8*, ...) @printf(i8* getelementptr inbounds ([73 x i8], [73 x i8]* @.str.7, i64 0, i64 0), i32 undef, i32 262143999, double %0, i32 524287999, double undef, i32 786431999, double undef, i32 1048575999, double undef)
+ ret void
+}
+
+declare dso_local void @printf(i8*, ...) local_unnamed_addr #1
+
+attributes #0 = { noinline optnone "frame-pointer"="all" "no-infs-fp-math"="false" }
+attributes #1 = { "use-soft-float"="false" }
Index: llvm/lib/Target/X86/X86RegisterInfo.cpp
===================================================================
--- llvm/lib/Target/X86/X86RegisterInfo.cpp
+++ llvm/lib/Target/X86/X86RegisterInfo.cpp
@@ -22,6 +22,7 @@
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
+#include "llvm/CodeGen/RegisterScavenging.h"
#include "llvm/CodeGen/TargetFrameLowering.h"
#include "llvm/CodeGen/TargetInstrInfo.h"
#include "llvm/IR/Constants.h"
@@ -778,8 +779,41 @@
// Offset is a 32-bit integer.
int Imm = (int)(MI.getOperand(FIOperandNum + 3).getImm());
int Offset = FIOffset + Imm;
- assert((!Is64Bit || isInt<32>((long long)FIOffset + Imm)) &&
- "Requesting 64-bit offset in 32-bit immediate!");
+
+ if (!isInt<32>((long long)FIOffset + Imm)) {
+ // Load the immediate into a register and use SIB addressing.
+ if (!Is64Bit)
+ report_fatal_error("Cannot lower large stack offset in 32-bit mode");
+
+ RegScavenger RS;
+
+ RS.enterBasicBlockEnd(MBB);
+ RS.backward(II);
+
+ // FIXME: Don't allow spilling because we may not be guaranteed to get a
+ // stack slot with a small offset, leading to infinite recursion trying to
+ // materialize the large offset in a register. This restriction can be
+ // lifted if register scavenger spills are always close to the frame or
+ // stack pointer.
+ Register OffsetReg = RS.scavengeRegisterBackwards(X86::GR64RegClass,
+ II,
+ /*RestoreAfter=*/false,
+ SPAdj,
+ /*AllowSpill=*/false);
+
+ if (!OffsetReg)
+ report_fatal_error("Could not find register for large stack offset");
+
+ const X86InstrInfo *TII = MF.getSubtarget<X86Subtarget>().getInstrInfo();
+
+ BuildMI(MBB, II, MI.getDebugLoc(), TII->get(X86::MOV64ri), OffsetReg).
+ addImm((long long)FIOffset + Imm);
+ MI.getOperand(FIOperandNum + X86::AddrIndexReg).setReg(OffsetReg);
+ MI.getOperand(FIOperandNum + X86::AddrIndexReg).setIsKill();
+ MI.getOperand(FIOperandNum + X86::AddrDisp).setImm(0);
+ return;
+ }
+
if (Offset != 0 || !tryOptimizeLEAtoMOV(II))
MI.getOperand(FIOperandNum + 3).ChangeToImmediate(Offset);
} else {
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D69534.226971.patch
Type: text/x-patch
Size: 4252 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20191029/546b8d38/attachment.bin>
More information about the llvm-commits
mailing list