[llvm] [X86][AsmParser] Reject negated scaled-index in Intel-syntax memory operands (PR #196219)

Iris Shi via llvm-commits llvm-commits at lists.llvm.org
Wed May 6 19:20:48 PDT 2026


https://github.com/el-ev updated https://github.com/llvm/llvm-project/pull/196219

>From eb5224841bcf6ac4bc730fe02c5afbdc73db13d5 Mon Sep 17 00:00:00 2001
From: Iris Shi <0.0 at owo.li>
Date: Thu, 7 May 2026 10:16:30 +0800
Subject: [PATCH] [X86][AsmParser] Reject negated scaled-index in Intel-syntax
 memory operands

---
 .../lib/Target/X86/AsmParser/X86AsmParser.cpp | 18 +++++++++++++
 .../inline-asm-intel-negated-scaled-index.ll  | 26 +++++++++++++++++++
 llvm/test/MC/X86/intel-syntax-invalid-scale.s |  6 +++++
 3 files changed, 50 insertions(+)
 create mode 100644 llvm/test/CodeGen/X86/inline-asm-intel-negated-scaled-index.ll

diff --git a/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp b/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp
index 49dff380b476a..0dd8ea115d451 100644
--- a/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp
+++ b/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp
@@ -218,6 +218,12 @@ class X86AsmParser : public MCTargetAsmParser {
     }
 
     void popOperator() { InfixOperatorStack.pop_back(); }
+    bool isOperatorStackTopNegating() const {
+      if (InfixOperatorStack.empty())
+        return false;
+      InfixCalculatorTok Top = InfixOperatorStack.back();
+      return Top == IC_MINUS || Top == IC_NEG;
+    }
     void pushOperator(InfixCalculatorTok Op) {
       // Push the new operator if the stack is empty.
       if (InfixOperatorStack.empty()) {
@@ -827,6 +833,13 @@ class X86AsmParser : public MCTargetAsmParser {
             return true;
           IC.pushOperand(IC_IMM);
           IC.popOperator();
+          // x86 SIB addressing has no way to subtract a scaled index
+          // register, so reject expressions like '[base - scale * index]'
+          // rather than silently dropping the sign.
+          if (IC.isOperatorStackTopNegating()) {
+            ErrMsg = "scaled index register cannot be negated";
+            return true;
+          }
         } else {
           State = IES_ERROR;
         }
@@ -907,6 +920,11 @@ class X86AsmParser : public MCTargetAsmParser {
             return true;
           // Get the scale and replace the 'Register * Scale' with '0'.
           IC.popOperator();
+          // Reject expressions like '[base - index * scale]'
+          if (IC.isOperatorStackTopNegating()) {
+            ErrMsg = "scaled index register cannot be negated";
+            return true;
+          }
         } else {
           IC.pushOperand(IC_IMM, TmpInt);
         }
diff --git a/llvm/test/CodeGen/X86/inline-asm-intel-negated-scaled-index.ll b/llvm/test/CodeGen/X86/inline-asm-intel-negated-scaled-index.ll
new file mode 100644
index 0000000000000..6766ede71214e
--- /dev/null
+++ b/llvm/test/CodeGen/X86/inline-asm-intel-negated-scaled-index.ll
@@ -0,0 +1,26 @@
+; RUN: not llc < %s -mtriple=x86_64-unknown-linux-gnu 2>&1 | FileCheck %s
+; Issue #196217
+
+; CHECK: error: scaled index register cannot be negated
+define i64 @minus_imm_times_reg(i64 %a, i64 %b) {
+  %r = call i64 asm sideeffect inteldialect "mov $0, [$0 - 2 * $1]", "=r,r,r"(i64 %a, i64 %b)
+  ret i64 %r
+}
+
+; CHECK: error: scaled index register cannot be negated
+define i64 @minus_imm_times_reg_with_disp(i64 %a, i64 %b) {
+  %r = call i64 asm sideeffect inteldialect "mov $0, [$0 - 2 * $1 + 8]", "=r,r,r"(i64 %a, i64 %b)
+  ret i64 %r
+}
+
+; CHECK: error: scaled index register cannot be negated
+define i64 @plus_then_minus_imm_times_reg(i64 %a, i64 %b) {
+  %r = call i64 asm sideeffect inteldialect "mov $0, [$0 + 8 - 4 * $1]", "=r,r,r"(i64 %a, i64 %b)
+  ret i64 %r
+}
+
+; CHECK: error: scaled index register cannot be negated
+define i64 @minus_one_times_reg(i64 %a, i64 %b) {
+  %r = call i64 asm sideeffect inteldialect "mov $0, [$0 - 1 * $1]", "=r,r,r"(i64 %a, i64 %b)
+  ret i64 %r
+}
diff --git a/llvm/test/MC/X86/intel-syntax-invalid-scale.s b/llvm/test/MC/X86/intel-syntax-invalid-scale.s
index 702f08a2f176f..b7c967e9fa3d5 100644
--- a/llvm/test/MC/X86/intel-syntax-invalid-scale.s
+++ b/llvm/test/MC/X86/intel-syntax-invalid-scale.s
@@ -13,3 +13,9 @@
     lea rax, [rdi + rdx*-8]
 // CHECK: error: scale factor in address must be 1, 2, 4 or 8
     lea rax, [rdi + -1*rdx]
+// CHECK: error: scaled index register cannot be negated
+    lea rax, [rdi - 2*rdx]
+// CHECK: error: scaled index register cannot be negated
+    lea rax, [rdi - 4*rdx + 8]
+// CHECK: error: scaled index register cannot be negated
+    lea rax, [rdi + 8 - 2*rdx]



More information about the llvm-commits mailing list