[llvm] 8d52097 - [X86] Use indirect addressing for high 2GB of x32 address space

Harald van Dijk via llvm-commits llvm-commits at lists.llvm.org
Wed Oct 11 11:20:56 PDT 2023


Author: Harald van Dijk
Date: 2023-10-11T19:20:36+01:00
New Revision: 8d520973b02b56fe75b9f916601dc1287a4cb17d

URL: https://github.com/llvm/llvm-project/commit/8d520973b02b56fe75b9f916601dc1287a4cb17d
DIFF: https://github.com/llvm/llvm-project/commit/8d520973b02b56fe75b9f916601dc1287a4cb17d.diff

LOG: [X86] Use indirect addressing for high 2GB of x32 address space

Instructions that take immediate addresses sign-extend their operands, so cannot be used when we actually need zero extension. Use indirect addressing to avoid problems.

The functions in the test are a modified versions of the functions by the same names in large-constants.ll, with i64 types changed to i32.

Fixes #55061

Reviewed By: RKSimon

Differential Revision: https://reviews.llvm.org/D124406

Added: 
    

Modified: 
    llvm/lib/Target/X86/X86ISelDAGToDAG.cpp
    llvm/test/CodeGen/X86/large-constants-x32.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Target/X86/X86ISelDAGToDAG.cpp b/llvm/lib/Target/X86/X86ISelDAGToDAG.cpp
index 694a2df195c0922..93e184eca9bc515 100644
--- a/llvm/lib/Target/X86/X86ISelDAGToDAG.cpp
+++ b/llvm/lib/Target/X86/X86ISelDAGToDAG.cpp
@@ -1699,10 +1699,28 @@ bool X86DAGToDAGISel::foldOffsetIntoAddress(uint64_t Offset,
     if (AM.BaseType == X86ISelAddressMode::FrameIndexBase &&
         !isDispSafeForFrameIndex(Val))
       return true;
+    // In ILP32 (x32) mode, pointers are 32 bits and need to be zero-extended to
+    // 64 bits. Instructions with 32-bit register addresses perform this zero
+    // extension for us and we can safely ignore the high bits of Offset.
+    // Instructions with only a 32-bit immediate address do not, though: they
+    // sign extend instead. This means only address the low 2GB of address space
+    // is directly addressable, we need indirect addressing for the high 2GB of
+    // address space.
+    // TODO: Some of the earlier checks may be relaxed for ILP32 mode as the
+    // implicit zero extension of instructions would cover up any problem.
+    // However, we have asserts elsewhere that get triggered if we do, so keep
+    // the checks for now.
+    // TODO: We would actually be able to accept these, as well as the same
+    // addresses in LP64 mode, by adding the EIZ pseudo-register as an operand
+    // to get an address size override to be emitted. However, this
+    // pseudo-register is not part of any register class and therefore causes
+    // MIR verification to fail.
+    if (Subtarget->isTarget64BitILP32() && !isUInt<31>(Val) &&
+        !AM.hasBaseOrIndexReg())
+      return true;
   }
   AM.Disp = Val;
   return false;
-
 }
 
 bool X86DAGToDAGISel::matchLoadInAddress(LoadSDNode *N, X86ISelAddressMode &AM,

diff  --git a/llvm/test/CodeGen/X86/large-constants-x32.ll b/llvm/test/CodeGen/X86/large-constants-x32.ll
index e875920b8b7054e..95a75006e085ada 100644
--- a/llvm/test/CodeGen/X86/large-constants-x32.ll
+++ b/llvm/test/CodeGen/X86/large-constants-x32.ll
@@ -4,12 +4,16 @@
 define void @constant_expressions() {
 ; CHECK-LABEL: constant_expressions:
 ; CHECK:       # %bb.0: # %entry
-; CHECK-NEXT:    movl -289477652, %eax
-; CHECK-NEXT:    movl -289477644, %ecx
-; CHECK-NEXT:    addl -289477648, %eax
-; CHECK-NEXT:    addl -289477636, %ecx
-; CHECK-NEXT:    addl %eax, %ecx
-; CHECK-NEXT:    movl %ecx, -289477652
+; CHECK-NEXT:    movl $-289477652, %eax # imm = 0xEEBEEBEC
+; CHECK-NEXT:    movl (%eax), %ecx
+; CHECK-NEXT:    movl $-289477644, %edx # imm = 0xEEBEEBF4
+; CHECK-NEXT:    movl (%edx), %edx
+; CHECK-NEXT:    movl $-289477648, %esi # imm = 0xEEBEEBF0
+; CHECK-NEXT:    addl (%esi), %ecx
+; CHECK-NEXT:    movl $-289477636, %esi # imm = 0xEEBEEBFC
+; CHECK-NEXT:    addl (%esi), %edx
+; CHECK-NEXT:    addl %ecx, %edx
+; CHECK-NEXT:    movl %edx, (%eax)
 ; CHECK-NEXT:    retq
 entry:
   %0 = load i32, i32* inttoptr (i32 add (i32 -289477652, i32 0) to i32*)
@@ -27,12 +31,16 @@ entry:
 define void @constant_expressions2() {
 ; CHECK-LABEL: constant_expressions2:
 ; CHECK:       # %bb.0: # %entry
-; CHECK-NEXT:    movl -289477652, %eax
-; CHECK-NEXT:    movl -289477644, %ecx
-; CHECK-NEXT:    addl -289477648, %eax
-; CHECK-NEXT:    addl -289477640, %ecx
-; CHECK-NEXT:    addl %eax, %ecx
-; CHECK-NEXT:    movl %ecx, -289477652
+; CHECK-NEXT:    movl $-289477652, %eax # imm = 0xEEBEEBEC
+; CHECK-NEXT:    movl (%eax), %ecx
+; CHECK-NEXT:    movl $-289477644, %edx # imm = 0xEEBEEBF4
+; CHECK-NEXT:    movl (%edx), %edx
+; CHECK-NEXT:    movl $-289477648, %esi # imm = 0xEEBEEBF0
+; CHECK-NEXT:    addl (%esi), %ecx
+; CHECK-NEXT:    movl $-289477640, %esi # imm = 0xEEBEEBF8
+; CHECK-NEXT:    addl (%esi), %edx
+; CHECK-NEXT:    addl %ecx, %edx
+; CHECK-NEXT:    movl %edx, (%eax)
 ; CHECK-NEXT:    retq
 entry:
   %0 = load i32, i32* inttoptr (i32 -289477652 to i32*)


        


More information about the llvm-commits mailing list