[llvm] [X86] Don't convert foo to foo(%rip) when the offset is near INT32_MIN (PR #98438)
Fangrui Song via llvm-commits
llvm-commits at lists.llvm.org
Thu Jul 11 13:36:33 PDT 2024
https://github.com/MaskRay updated https://github.com/llvm/llvm-project/pull/98438
>From 698da3bebcb2e78d258f96ea7f3feb07c06f040e Mon Sep 17 00:00:00 2001
From: Fangrui Song <i at maskray.me>
Date: Wed, 10 Jul 2024 23:39:41 -0700
Subject: [PATCH] =?UTF-8?q?[=F0=9D=98=80=F0=9D=97=BD=F0=9D=97=BF]=20initia?=
=?UTF-8?q?l=20version?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Created using spr 1.3.5-bogner
---
llvm/lib/Target/X86/X86ISelDAGToDAG.cpp | 7 ++
llvm/test/CodeGen/X86/fold-add.ll | 98 ++++++++++++++++++++++++-
2 files changed, 103 insertions(+), 2 deletions(-)
diff --git a/llvm/lib/Target/X86/X86ISelDAGToDAG.cpp b/llvm/lib/Target/X86/X86ISelDAGToDAG.cpp
index c91bd576dc9f6..e06de1c4276a3 100644
--- a/llvm/lib/Target/X86/X86ISelDAGToDAG.cpp
+++ b/llvm/lib/Target/X86/X86ISelDAGToDAG.cpp
@@ -1795,6 +1795,13 @@ bool X86DAGToDAGISel::foldOffsetIntoAddress(uint64_t Offset,
!X86::isOffsetSuitableForCodeModel(Val, M,
AM.hasSymbolicDisplacement()))
return true;
+ // When Sym is a local symbol in ELF, leaq Sym+Offset(%rip) in non-large
+ // code models generates a relocation referencing the section symbol. Don't
+ // fold offsets that are too closer to INT32_MIN, as the addend could
+ // underflow.
+ if (Val < INT32_MIN + 256 * 1024 * 1024 && M != CodeModel::Large &&
+ AM.hasSymbolicDisplacement())
+ return true;
// In addition to the checks required for a register base, check that
// we do not try to use an unsafe Disp with a frame index.
if (AM.BaseType == X86ISelAddressMode::FrameIndexBase &&
diff --git a/llvm/test/CodeGen/X86/fold-add.ll b/llvm/test/CodeGen/X86/fold-add.ll
index 8c28d66597fb3..f7659c9cf0653 100644
--- a/llvm/test/CodeGen/X86/fold-add.ll
+++ b/llvm/test/CodeGen/X86/fold-add.ll
@@ -118,17 +118,46 @@ entry:
ret i64 add (i64 ptrtoint (ptr @foo to i64), i64 -1)
}
+define dso_local i64 @neg_0x70000000() #0 {
+; STATIC-LABEL: neg_0x70000000:
+; STATIC: # %bb.0: # %entry
+; STATIC-NEXT: leaq foo-1879048192(%rip), %rax
+; STATIC-NEXT: retq
+;
+; PIC-LABEL: neg_0x70000000:
+; PIC: # %bb.0: # %entry
+; PIC-NEXT: leaq foo-1879048192(%rip), %rax
+; PIC-NEXT: retq
+;
+; MSTATIC-LABEL: neg_0x70000000:
+; MSTATIC: # %bb.0: # %entry
+; MSTATIC-NEXT: movabsq $foo, %rax
+; MSTATIC-NEXT: addq $-1879048192, %rax # imm = 0x90000000
+; MSTATIC-NEXT: retq
+;
+; MPIC-LABEL: neg_0x70000000:
+; MPIC: # %bb.0: # %entry
+; MPIC-NEXT: leaq _GLOBAL_OFFSET_TABLE_(%rip), %rax
+; MPIC-NEXT: movabsq $foo at GOTOFF, %rcx
+; MPIC-NEXT: leaq -1879048192(%rax,%rcx), %rax
+; MPIC-NEXT: retq
+entry:
+ ret i64 add (i64 ptrtoint (ptr @foo to i64), i64 -1879048192)
+}
+
;; Test we don't emit movl foo-2147483648, %eax. ELF R_X86_64_32 does not allow
;; a negative value.
define dso_local i64 @neg_0x80000000() #0 {
; STATIC-LABEL: neg_0x80000000:
; STATIC: # %bb.0: # %entry
-; STATIC-NEXT: leaq foo-2147483648(%rip), %rax
+; STATIC-NEXT: movq $-2147483648, %rax # imm = 0x80000000
+; STATIC-NEXT: leaq foo(%rax), %rax
; STATIC-NEXT: retq
;
; PIC-LABEL: neg_0x80000000:
; PIC: # %bb.0: # %entry
-; PIC-NEXT: leaq foo-2147483648(%rip), %rax
+; PIC-NEXT: leaq foo(%rip), %rax
+; PIC-NEXT: addq $-2147483648, %rax # imm = 0x80000000
; PIC-NEXT: retq
;
; MSTATIC-LABEL: neg_0x80000000:
@@ -180,4 +209,69 @@ entry:
ret i64 add (i64 ptrtoint (ptr @foo to i64), i64 -2147483649)
}
+define internal void @bar() #0 {
+; STATIC-LABEL: bar:
+; STATIC: # %bb.0:
+; STATIC-NEXT: retq
+;
+; PIC-LABEL: bar:
+; PIC: # %bb.0:
+; PIC-NEXT: retq
+;
+; MSTATIC-LABEL: bar:
+; MSTATIC: # %bb.0:
+; MSTATIC-NEXT: retq
+;
+; MPIC-LABEL: bar:
+; MPIC: # %bb.0:
+; MPIC-NEXT: retq
+ ret void
+}
+
+define dso_local i64 @fun_neg_0x6fffffff() #0 {
+; STATIC-LABEL: fun_neg_0x6fffffff:
+; STATIC: # %bb.0:
+; STATIC-NEXT: leaq bar-1879048191(%rip), %rax
+; STATIC-NEXT: retq
+;
+; PIC-LABEL: fun_neg_0x6fffffff:
+; PIC: # %bb.0:
+; PIC-NEXT: leaq bar-1879048191(%rip), %rax
+; PIC-NEXT: retq
+;
+; MSTATIC-LABEL: fun_neg_0x6fffffff:
+; MSTATIC: # %bb.0:
+; MSTATIC-NEXT: leaq bar-1879048191(%rip), %rax
+; MSTATIC-NEXT: retq
+;
+; MPIC-LABEL: fun_neg_0x6fffffff:
+; MPIC: # %bb.0:
+; MPIC-NEXT: leaq bar-1879048191(%rip), %rax
+; MPIC-NEXT: retq
+ ret i64 add (i64 ptrtoint (ptr @bar to i64), i64 -1879048191)
+}
+
+define dso_local i64 @fun_neg_0x70000000() #0 {
+; STATIC-LABEL: fun_neg_0x70000000:
+; STATIC: # %bb.0:
+; STATIC-NEXT: leaq bar-1879048192(%rip), %rax
+; STATIC-NEXT: retq
+;
+; PIC-LABEL: fun_neg_0x70000000:
+; PIC: # %bb.0:
+; PIC-NEXT: leaq bar-1879048192(%rip), %rax
+; PIC-NEXT: retq
+;
+; MSTATIC-LABEL: fun_neg_0x70000000:
+; MSTATIC: # %bb.0:
+; MSTATIC-NEXT: leaq bar-1879048192(%rip), %rax
+; MSTATIC-NEXT: retq
+;
+; MPIC-LABEL: fun_neg_0x70000000:
+; MPIC: # %bb.0:
+; MPIC-NEXT: leaq bar-1879048192(%rip), %rax
+; MPIC-NEXT: retq
+ ret i64 add (i64 ptrtoint (ptr @bar to i64), i64 -1879048192)
+}
+
attributes #0 = { nounwind }
More information about the llvm-commits
mailing list