Skip to content

Commit dccbf33

Browse files
committed
Fix X86 Target overflows
Remove i386 test case since > 4gb allocas cannot be serviced on that platform
1 parent 81515ce commit dccbf33

File tree

5 files changed

+62
-42
lines changed

5 files changed

+62
-42
lines changed

llvm/lib/Target/X86/X86FrameLowering.cpp

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
#include "llvm/CodeGen/MachineInstrBuilder.h"
2525
#include "llvm/CodeGen/MachineModuleInfo.h"
2626
#include "llvm/CodeGen/MachineRegisterInfo.h"
27+
#include "llvm/CodeGen/RegisterScavenging.h"
2728
#include "llvm/CodeGen/WinEHFuncInfo.h"
2829
#include "llvm/IR/DataLayout.h"
2930
#include "llvm/IR/EHPersonalities.h"
@@ -2616,7 +2617,7 @@ StackOffset X86FrameLowering::getFrameIndexReference(const MachineFunction &MF,
26162617
// object.
26172618
// We need to factor in additional offsets applied during the prologue to the
26182619
// frame, base, and stack pointer depending on which is used.
2619-
int Offset = MFI.getObjectOffset(FI) - getOffsetOfLocalArea();
2620+
int64_t Offset = MFI.getObjectOffset(FI) - getOffsetOfLocalArea();
26202621
const X86MachineFunctionInfo *X86FI = MF.getInfo<X86MachineFunctionInfo>();
26212622
unsigned CSSize = X86FI->getCalleeSavedFrameSize();
26222623
uint64_t StackSize = MFI.getStackSize();
@@ -4140,6 +4141,14 @@ void X86FrameLowering::processFunctionBeforeFrameFinalized(
41404141
// emitPrologue if it gets called and emits CFI.
41414142
MF.setHasWinCFI(false);
41424143

4144+
MachineFrameInfo &MFI = MF.getFrameInfo();
4145+
// If the frame is big enough that we might need to scavenge a register to
4146+
// handle huge offsets, reserve a stack slot for that now.
4147+
if (!isInt<32>(MFI.estimateStackSize(MF))) {
4148+
int FI = MFI.CreateStackObject(SlotSize, Align(SlotSize), false);
4149+
RS->addScavengingFrameIndex(FI);
4150+
}
4151+
41434152
// If we are using Windows x64 CFI, ensure that the stack is always 8 byte
41444153
// aligned. The format doesn't support misaligned stack adjustments.
41454154
if (MF.getTarget().getMCAsmInfo()->usesWindowsCFI())

llvm/lib/Target/X86/X86RegisterInfo.cpp

Lines changed: 32 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
//===----------------------------------------------------------------------===//
1414

1515
#include "X86RegisterInfo.h"
16+
#include "MCTargetDesc/X86BaseInfo.h"
1617
#include "X86FrameLowering.h"
1718
#include "X86MachineFunctionInfo.h"
1819
#include "X86Subtarget.h"
@@ -24,6 +25,7 @@
2425
#include "llvm/CodeGen/MachineFunction.h"
2526
#include "llvm/CodeGen/MachineFunctionPass.h"
2627
#include "llvm/CodeGen/MachineRegisterInfo.h"
28+
#include "llvm/CodeGen/RegisterScavenging.h"
2729
#include "llvm/CodeGen/TargetFrameLowering.h"
2830
#include "llvm/CodeGen/TargetInstrInfo.h"
2931
#include "llvm/CodeGen/TileShapeInfo.h"
@@ -900,7 +902,7 @@ X86RegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
900902
int FrameIndex = MI.getOperand(FIOperandNum).getIndex();
901903

902904
// Determine base register and offset.
903-
int FIOffset;
905+
int64_t FIOffset;
904906
Register BasePtr;
905907
if (MI.isReturn()) {
906908
assert((!hasStackRealignment(MF) ||
@@ -951,11 +953,35 @@ X86RegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
951953
}
952954

953955
if (MI.getOperand(FIOperandNum+3).isImm()) {
954-
// Offset is a 32-bit integer.
955-
int Imm = (int)(MI.getOperand(FIOperandNum + 3).getImm());
956-
int Offset = FIOffset + Imm;
957-
assert((!Is64Bit || isInt<32>((long long)FIOffset + Imm)) &&
958-
"Requesting 64-bit offset in 32-bit immediate!");
956+
int64_t Imm = MI.getOperand(FIOperandNum + 3).getImm();
957+
int64_t Offset = FIOffset + Imm;
958+
bool FitsIn32Bits = isInt<32>(Offset);
959+
// If the offset will not fit in a 32-bit displacement,
960+
// then for 64-bit targets, scavenge a register to hold it.
961+
// Otherwise, for 32-bit targets, this is a bug!
962+
if (Is64Bit && !FitsIn32Bits) {
963+
assert(RS && "RegisterScavenger was NULL");
964+
const X86InstrInfo *TII = MF.getSubtarget<X86Subtarget>().getInstrInfo();
965+
const DebugLoc &DL = MI.getDebugLoc();
966+
967+
RS->enterBasicBlockEnd(MBB);
968+
RS->backward(std::next(II));
969+
970+
Register ScratchReg =
971+
RS->scavengeRegisterBackwards(X86::GR64RegClass, II, /* RestoreAfter */ false, /* SPAdj */ 0, /* AllowSpill */ true);
972+
assert(ScratchReg != 0 && "scratch reg was 0");
973+
RS->setRegUsed(ScratchReg);
974+
975+
BuildMI(MBB, II, DL, TII->get(X86::MOV64ri), ScratchReg).addImm(Offset);
976+
977+
MI.getOperand(FIOperandNum + 3).setImm(0);
978+
MI.getOperand(FIOperandNum + 2).setReg(ScratchReg);
979+
980+
return false;
981+
}
982+
if (!Is64Bit) {
983+
assert(FitsIn32Bits && "Requesting 64-bit offset in 32-bit immediate!");
984+
}
959985
if (Offset != 0 || !tryOptimizeLEAtoMOV(II))
960986
MI.getOperand(FIOperandNum + 3).ChangeToImmediate(Offset);
961987
} else {

llvm/test/CodeGen/X86/huge-stack-offset.ll

Lines changed: 13 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,15 @@
1-
; RUN: llc < %s -mtriple=x86_64-linux-unknown -verify-machineinstrs | FileCheck %s --check-prefix=CHECK-64
2-
; RUN: llc < %s -mtriple=i386-linux-unknown -verify-machineinstrs | FileCheck %s --check-prefix=CHECK-32
1+
; RUN: llc < %s -mtriple=x86_64-linux-unknown -verify-machineinstrs | FileCheck %s
32

43
; Test that a large stack offset uses a single add/sub instruction to
54
; adjust the stack pointer.
65

76
define void @foo() nounwind {
8-
; CHECK-64-LABEL: foo:
9-
; CHECK-64: movabsq $50000000{{..}}, %rax
10-
; CHECK-64-NEXT: subq %rax, %rsp
11-
; CHECK-64-NOT: subq $2147483647, %rsp
12-
; CHECK-64: movabsq $50000000{{..}}, [[RAX:%r..]]
13-
; CHECK-64-NEXT: addq [[RAX]], %rsp
14-
15-
; CHECK-32-LABEL: foo:
16-
; CHECK-32: movl $50000000{{..}}, %eax
17-
; CHECK-32-NEXT: subl %eax, %esp
18-
; CHECK-32-NOT: subl $2147483647, %esp
19-
; CHECK-32: movl $50000000{{..}}, [[EAX:%e..]]
20-
; CHECK-32-NEXT: addl [[EAX]], %esp
7+
; CHECK--LABEL: foo:
8+
; CHECK: movabsq $50000000{{..}}, %rax
9+
; CHECK-NEXT: subq %rax, %rsp
10+
; CHECK-NOT: subq $2147483647, %rsp
11+
; CHECK: movabsq $50000000{{..}}, [[RAX:%r..]]
12+
; CHECK-NEXT: addq [[RAX]], %rsp
2113
%1 = alloca [5000000000 x i8], align 16
2214
call void @bar(ptr %1)
2315
ret void
@@ -26,13 +18,9 @@ define void @foo() nounwind {
2618
; Verify that we do not clobber the return value.
2719

2820
define i32 @foo2() nounwind {
29-
; CHECK-64-LABEL: foo2:
30-
; CHECK-64: movl $10, %eax
31-
; CHECK-64-NOT: movabsq ${{.*}}, %rax
32-
33-
; CHECK-32-LABEL: foo2:
34-
; CHECK-32: movl $10, %eax
35-
; CHECK-32-NOT: movl ${{.*}}, %eax
21+
; CHECK-LABEL: foo2:
22+
; CHECK: movl $10, %eax
23+
; CHECK-NOT: movabsq ${{.*}}, %rax
3624
%1 = alloca [5000000000 x i8], align 16
3725
call void @bar(ptr %1)
3826
ret i32 10
@@ -41,13 +29,9 @@ define i32 @foo2() nounwind {
4129
; Verify that we do not clobber EAX when using inreg attribute
4230

4331
define i32 @foo3(i32 inreg %x) nounwind {
44-
; CHECK-64-LABEL: foo3:
45-
; CHECK-64: movabsq $50000000{{..}}, %rax
46-
; CHECK-64-NEXT: subq %rax, %rsp
47-
48-
; CHECK-32-LABEL: foo3:
49-
; CHECK-32: subl $2147483647, %esp
50-
; CHECK-32-NOT: movl ${{.*}}, %eax
32+
; CHECK-LABEL: foo3:
33+
; CHECK: movabsq $50000000{{..}}, %rax
34+
; CHECK-NEXT: subq %rax, %rsp
5135
%1 = alloca [5000000000 x i8], align 16
5236
call void @bar(ptr %1)
5337
ret i32 %x

llvm/test/CodeGen/X86/huge-stack.ll

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,13 @@
55
define void @foo() unnamed_addr #0 {
66
; CHECK-LABEL: foo:
77
; CHECK: # %bb.0:
8-
; CHECK-NEXT: movabsq $8589934462, %rax # imm = 0x1FFFFFF7E
8+
; CHECK-NEXT: movabsq $8589934472, %rax # imm = 0x1FFFFFF88
99
; CHECK-NEXT: subq %rax, %rsp
10-
; CHECK-NEXT: .cfi_def_cfa_offset 8589934470
11-
; CHECK-NEXT: movb $42, -129(%rsp)
12-
; CHECK-NEXT: movb $43, -128(%rsp)
13-
; CHECK-NEXT: movabsq $8589934462, %rax # imm = 0x1FFFFFF7E
10+
; CHECK-NEXT: .cfi_def_cfa_offset 8589934480
11+
; CHECK-NEXT: movabsq $4294967177, %rax # imm = 0xFFFFFF89
12+
; CHECK-NEXT: movb $42, (%rsp,%rax)
13+
; CHECK-NEXT: movb $43, -118(%rsp)
14+
; CHECK-NEXT: movabsq $8589934472, %rax # imm = 0x1FFFFFF88
1415
; CHECK-NEXT: addq %rax, %rsp
1516
; CHECK-NEXT: .cfi_def_cfa_offset 8
1617
; CHECK-NEXT: retq

llvm/test/CodeGen/X86/win64-stackprobe-overflow.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,5 +10,5 @@ start:
1010
attributes #0 = { nonlazybind uwtable "probe-stack"="probe_stack" "target-cpu"="x86-64" }
1111

1212
; CHECK-LABEL: foo:
13-
; CHECK: movabsq $4294967304, %rax
13+
; CHECK: movabsq $4294967312, %rax
1414
; CHECK-NEXT: callq probe_stack

0 commit comments

Comments
 (0)