[llvm] [X86] Fix 32-bit immediate assertion and convert into backend error (PR #123872)

Wesley Wiser via llvm-commits llvm-commits at lists.llvm.org
Sat Feb 8 09:32:32 PST 2025


https://github.com/wesleywiser updated https://github.com/llvm/llvm-project/pull/123872

>From 79d4afd573b0f22f487a2713b168408ac4b1d1b7 Mon Sep 17 00:00:00 2001
From: Wesley Wiser <wwiser at gmail.com>
Date: Sun, 5 Jan 2025 05:09:35 +0000
Subject: [PATCH] [X86] Fix 32-bit immediate assertion and convert into backend
 error

The assertion previously did not work correctly because the operand was
being truncated to an `int` prior to comparison.
---
 llvm/lib/Target/X86/X86RegisterInfo.cpp       |  9 ++--
 .../X86/large-displacements-fastisel.ll       | 17 ++++++++
 llvm/test/CodeGen/X86/large-displacements.ll  | 43 +++++++++++++++++++
 3 files changed, 64 insertions(+), 5 deletions(-)
 create mode 100644 llvm/test/CodeGen/X86/large-displacements-fastisel.ll
 create mode 100644 llvm/test/CodeGen/X86/large-displacements.ll

diff --git a/llvm/lib/Target/X86/X86RegisterInfo.cpp b/llvm/lib/Target/X86/X86RegisterInfo.cpp
index 4faf8bca4f9e021..9c1a2806fd8532c 100644
--- a/llvm/lib/Target/X86/X86RegisterInfo.cpp
+++ b/llvm/lib/Target/X86/X86RegisterInfo.cpp
@@ -965,11 +965,10 @@ X86RegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
   }
 
   if (MI.getOperand(FIOperandNum+3).isImm()) {
-    // Offset is a 32-bit integer.
-    int Imm = (int)(MI.getOperand(FIOperandNum + 3).getImm());
-    int Offset = FIOffset + Imm;
-    assert((!Is64Bit || isInt<32>((long long)FIOffset + Imm)) &&
-           "Requesting 64-bit offset in 32-bit immediate!");
+    int64_t Imm = MI.getOperand(FIOperandNum + 3).getImm();
+    int Offset = FIOffset + (int)Imm;
+    if (!Is64Bit && !isInt<32>((int64_t)FIOffset + Imm))
+      MI.emitGenericError("requesting 64-bit offset in 32-bit immediate");
     if (Offset != 0 || !tryOptimizeLEAtoMOV(II))
       MI.getOperand(FIOperandNum + 3).ChangeToImmediate(Offset);
   } else {
diff --git a/llvm/test/CodeGen/X86/large-displacements-fastisel.ll b/llvm/test/CodeGen/X86/large-displacements-fastisel.ll
new file mode 100644
index 000000000000000..64c3132976f738b
--- /dev/null
+++ b/llvm/test/CodeGen/X86/large-displacements-fastisel.ll
@@ -0,0 +1,17 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5
+; RUN: llc < %s -mtriple=x86_64 -O=0 | FileCheck %s
+ at G = global i8 0
+
+; Regression test for #113856 - incorrect FastISel assert
+
+define dso_local i32 @main() #0 {
+; CHECK-LABEL: main:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    movl $0, {{[0-9]+}}(%rsp)
+; CHECK-NEXT:    xorl %eax, %eax
+; CHECK-NEXT:    retq
+  %1 = alloca i32, align 4
+  %G = getelementptr i8, ptr %1, i32 -2147483648
+  store i32 0, ptr %G, align 4
+  ret i32 0
+}
diff --git a/llvm/test/CodeGen/X86/large-displacements.ll b/llvm/test/CodeGen/X86/large-displacements.ll
new file mode 100644
index 000000000000000..da2703d09db4b20
--- /dev/null
+++ b/llvm/test/CodeGen/X86/large-displacements.ll
@@ -0,0 +1,43 @@
+; RUN: not llc < %s -mtriple=i686 -filetype=null 2>&1 | FileCheck %s -check-prefix=ERR-i686
+; RUN: llc < %s -mtriple=x86_64 | FileCheck %s -check-prefix=x86_64
+
+; Regression test for #121932, #113856, #106352, #69365, #25051 which are caused by
+; an incorrectly written assertion for 64-bit offsets when compiling for 32-bit X86.
+
+define i32 @main() #0 {
+; ERR-i686: error: <unknown>:0:0: requesting 64-bit offset in 32-bit immediate
+;
+; x86_64-LABEL: main:
+; x86_64:       # %bb.0: # %entry
+; x86_64-NEXT:    movl $4294967176, %eax # imm = 0xFFFFFF88
+; x86_64-NEXT:    subq %rax, %rsp
+; x86_64-NEXT:    .cfi_def_cfa_offset 4294967184
+; x86_64-NEXT:    movb $32, -1073741994(%rsp)
+; x86_64-NEXT:    movb $33, 2147483478(%rsp)
+; x86_64-NEXT:    movb $34, 1073741654(%rsp)
+; x86_64-NEXT:    movb $35, -170(%rsp)
+; x86_64-NEXT:    xorl %eax, %eax
+; x86_64-NEXT:    movl $4294967176, %ecx # imm = 0xFFFFFF88
+; x86_64-NEXT:    addq %rcx, %rsp
+; x86_64-NEXT:    .cfi_def_cfa_offset 8
+; x86_64-NEXT:    retq
+entry:
+  %a = alloca [1073741824 x i8], align 16
+  %b = alloca [1073741824 x i8], align 16
+  %c = alloca [1073741824 x i8], align 16
+  %d = alloca [1073741824 x i8], align 16
+
+  %arrayida = getelementptr inbounds [1073741824 x i8], ptr %a, i64 0, i64 -42
+  %arrayidb = getelementptr inbounds [1073741824 x i8], ptr %b, i64 0, i64 -42
+  %arrayidc = getelementptr inbounds [1073741824 x i8], ptr %c, i64 0, i64 -42
+  %arrayidd = getelementptr inbounds [1073741824 x i8], ptr %d, i64 0, i64 -42
+
+  store i8 32, ptr %arrayida, align 2
+  store i8 33, ptr %arrayidb, align 2
+  store i8 34, ptr %arrayidc, align 2
+  store i8 35, ptr %arrayidd, align 2
+
+  ret i32 0
+}
+
+attributes #0 = { optnone noinline }



More information about the llvm-commits mailing list