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

Harald van Dijk via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Mon Apr 25 10:14:35 PDT 2022


hvdijk created this revision.
hvdijk added reviewers: craig.topper, RKSimon.
hvdijk added a project: LLVM.
Herald added subscribers: StephenFan, pengfei, hiraditya.
Herald added a project: All.
hvdijk requested review of this revision.
Herald added a subscriber: llvm-commits.

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


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D124406

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


Index: llvm/test/CodeGen/X86/large-constants-x32.ll
===================================================================
--- /dev/null
+++ llvm/test/CodeGen/X86/large-constants-x32.ll
@@ -0,0 +1,55 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc < %s -mtriple=x86_64-linux-gnux32 | FileCheck %s
+
+define void @constant_expressions() {
+; CHECK-LABEL: constant_expressions:
+; CHECK:       # %bb.0: # %entry
+; CHECK-NEXT:    movl $-289477652, %eax # imm = 0xEEBEEBEC
+; CHECK-NEXT:    movl (%eax), %ecx
+; CHECK-NEXT:    movl $-289477636, %edx # imm = 0xEEBEEBFC
+; CHECK-NEXT:    movl (%edx), %edx
+; CHECK-NEXT:    movl $-289477644, %esi # imm = 0xEEBEEBF4
+; CHECK-NEXT:    addl (%esi), %ecx
+; CHECK-NEXT:    movl $-289477628, %esi # imm = 0xEEBEEC04
+; 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*)
+  %1 = load i32, i32* inttoptr (i32 add (i32 -289477652, i32 8) to i32*)
+  %2 = load i32, i32* inttoptr (i32 add (i32 -289477652, i32 16) to i32*)
+  %3 = load i32, i32* inttoptr (i32 add (i32 -289477652, i32 24) to i32*)
+  %4 = add i32 %0, %1
+  %5 = add i32 %2, %3
+  %6 = add i32 %4, %5
+  store i32 %6, i32* inttoptr (i32 add (i32 -289477652, i32 0) to i32*)
+  ret void
+}
+
+
+define void @constant_expressions2() {
+; CHECK-LABEL: constant_expressions2:
+; CHECK:       # %bb.0: # %entry
+; CHECK-NEXT:    movl $-289477652, %eax # imm = 0xEEBEEBEC
+; CHECK-NEXT:    movl (%eax), %ecx
+; CHECK-NEXT:    movl $-289477636, %edx # imm = 0xEEBEEBFC
+; CHECK-NEXT:    movl (%edx), %edx
+; CHECK-NEXT:    movl $-289477644, %esi # imm = 0xEEBEEBF4
+; CHECK-NEXT:    addl (%esi), %ecx
+; CHECK-NEXT:    movl $-289477628, %esi # imm = 0xEEBEEC04
+; 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*)
+  %1 = load i32, i32* inttoptr (i32 -289477644 to i32*)
+  %2 = load i32, i32* inttoptr (i32 -289477636 to i32*)
+  %3 = load i32, i32* inttoptr (i32 -289477628 to i32*)
+  %4 = add i32 %0, %1
+  %5 = add i32 %2, %3
+  %6 = add i32 %4, %5
+  store i32 %6, i32* inttoptr (i32 -289477652 to i32*)
+  ret void
+}
Index: llvm/lib/Target/X86/X86ISelDAGToDAG.cpp
===================================================================
--- llvm/lib/Target/X86/X86ISelDAGToDAG.cpp
+++ llvm/lib/Target/X86/X86ISelDAGToDAG.cpp
@@ -1681,10 +1681,23 @@
     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.
+    if (Subtarget->isTarget64BitILP32() && !isUInt<31>(Val) &&
+        !AM.hasBaseOrIndexReg())
+      return true;
   }
   AM.Disp = Val;
   return false;
-
 }
 
 bool X86DAGToDAGISel::matchLoadInAddress(LoadSDNode *N, X86ISelAddressMode &AM,


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D124406.424956.patch
Type: text/x-patch
Size: 3721 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20220425/941fcd2d/attachment.bin>


More information about the llvm-commits mailing list