Skip to content

Commit a9b4ae1

Browse files
committed
[X86] Don't fold very large offsets into addr displacements during ISel
Doing so can cause the resulting displacement after frame layout to become inexpressible (or cause over/underflow currently during frame layout).
1 parent 49f9946 commit a9b4ae1

File tree

3 files changed

+14
-8
lines changed

3 files changed

+14
-8
lines changed

llvm/lib/Target/X86/X86ISelDAGToDAG.cpp

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1800,10 +1800,10 @@ void X86DAGToDAGISel::emitFunctionEntryCode() {
18001800
emitSpecialCodeForMain();
18011801
}
18021802

1803-
static bool isDispSafeForFrameIndex(int64_t Val) {
1804-
// On 64-bit platforms, we can run into an issue where a frame index
1803+
static bool isDispSafeForFrameIndexOrRegBase(int64_t Val) {
1804+
// We can run into an issue where a frame index or a register base
18051805
// includes a displacement that, when added to the explicit displacement,
1806-
// will overflow the displacement field. Assuming that the frame index
1806+
// will overflow the displacement field. Assuming that the
18071807
// displacement fits into a 31-bit integer (which is only slightly more
18081808
// aggressive than the current fundamental assumption that it fits into
18091809
// a 32-bit integer), a 31-bit disp should always be safe.
@@ -1831,7 +1831,7 @@ bool X86DAGToDAGISel::foldOffsetIntoAddress(uint64_t Offset,
18311831
// In addition to the checks required for a register base, check that
18321832
// we do not try to use an unsafe Disp with a frame index.
18331833
if (AM.BaseType == X86ISelAddressMode::FrameIndexBase &&
1834-
!isDispSafeForFrameIndex(Val))
1834+
!isDispSafeForFrameIndexOrRegBase(Val))
18351835
return true;
18361836
// In ILP32 (x32) mode, pointers are 32 bits and need to be zero-extended to
18371837
// 64 bits. Instructions with 32-bit register addresses perform this zero
@@ -1852,7 +1852,10 @@ bool X86DAGToDAGISel::foldOffsetIntoAddress(uint64_t Offset,
18521852
if (Subtarget->isTarget64BitILP32() && !isUInt<31>(Val) &&
18531853
!AM.hasBaseOrIndexReg())
18541854
return true;
1855-
}
1855+
} else if (AM.hasBaseOrIndexReg() && !isDispSafeForFrameIndexOrRegBase(Val))
1856+
// For 32-bit X86, make sure the displacement still isn't close to the
1857+
// expressible limit.
1858+
return true;
18561859
AM.Disp = Val;
18571860
return false;
18581861
}
@@ -2553,7 +2556,7 @@ bool X86DAGToDAGISel::matchAddressRecursively(SDValue N, X86ISelAddressMode &AM,
25532556
case ISD::FrameIndex:
25542557
if (AM.BaseType == X86ISelAddressMode::RegBase &&
25552558
AM.Base_Reg.getNode() == nullptr &&
2556-
(!Subtarget->is64Bit() || isDispSafeForFrameIndex(AM.Disp))) {
2559+
(!Subtarget->is64Bit() || isDispSafeForFrameIndexOrRegBase(AM.Disp))) {
25572560
AM.BaseType = X86ISelAddressMode::FrameIndexBase;
25582561
AM.Base_FrameIndex = cast<FrameIndexSDNode>(N)->getIndex();
25592562
return false;

llvm/test/CodeGen/X86/dag-large-offset.ll

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,9 @@ define dso_local noundef i32 @foo(i1 %b) local_unnamed_addr #0 {
1111
; CHECK-NEXT: movl ___security_cookie, %eax
1212
; CHECK-NEXT: xorl %ebp, %eax
1313
; CHECK-NEXT: movl %eax, -8(%ebp)
14-
; CHECK-NEXT: leal 2147483640(%ebp), %eax
14+
; CHECK-NEXT: movl $-2147483647, %eax # imm = 0x80000001
15+
; CHECK-NEXT: addl %ebp, %eax
16+
; CHECK-NEXT: addl $-9, %eax
1517
; CHECK-NEXT: xorl %esi, %esi
1618
; CHECK-NEXT: testb $1, 8(%ebp)
1719
; CHECK-NEXT: cmovnel %eax, %esi

llvm/test/CodeGen/X86/xor-lea.ll

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -327,7 +327,8 @@ define i32 @xor_shl_sminval_i32(i32 %x) {
327327
; X86-LABEL: xor_shl_sminval_i32:
328328
; X86: # %bb.0:
329329
; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
330-
; X86-NEXT: leal -2147483648(,%eax,8), %eax
330+
; X86-NEXT: movl $-2147483648, %ecx # imm = 0x80000000
331+
; X86-NEXT: leal (%ecx,%eax,8), %eax
331332
; X86-NEXT: retl
332333
;
333334
; X64-LABEL: xor_shl_sminval_i32:

0 commit comments

Comments
 (0)