[llvm] Validate immediates for SCVTF, UCVTF and EXT (PR #214233)

Hamza Khan via llvm-commits llvm-commits at lists.llvm.org
Wed Aug 5 07:20:23 PDT 2026


https://github.com/HamzaKodez updated https://github.com/llvm/llvm-project/pull/214233

>From 9a124f39b392442c30a54ad123350d1c9db58de7 Mon Sep 17 00:00:00 2001
From: Hamza Khan <hamza.khan at arm.com>
Date: Thu, 23 Jul 2026 13:51:00 +0100
Subject: [PATCH] Validate immediates for SCVTF, UCVTF and EXT

Reject symbolic operands where fixed-point scale and EXT byte-index
integer immediates are required.

This prevents assertion failures in assertions-enabled builds and
incorrect encodings in assertions-disabled builds.

Add MC regression tests for the affected instructions.

Assisted-by ChatGPT. Human-reviewed, debugged, tested, and validated by the author.
---
 llvm/lib/Target/AArch64/AArch64InstrFormats.td | 10 ++++++----
 llvm/test/MC/AArch64/arm64-diags.s             | 18 ++++++++++++++++++
 llvm/test/MC/AArch64/neon-diagnostics.s        |  9 +++++++++
 3 files changed, 33 insertions(+), 4 deletions(-)

diff --git a/llvm/lib/Target/AArch64/AArch64InstrFormats.td b/llvm/lib/Target/AArch64/AArch64InstrFormats.td
index 58fc5ec063c15..56b98a85948a3 100644
--- a/llvm/lib/Target/AArch64/AArch64InstrFormats.td
+++ b/llvm/lib/Target/AArch64/AArch64InstrFormats.td
@@ -882,6 +882,7 @@ class fixedpoint_recip_i32<ValueType FloatVT>
   let EncoderMethod = "getFixedPointScaleOpValue";
   let DecoderMethod = "DecodeFixedPointScaleImm32";
   let OperandType = "OPERAND_IMMEDIATE";
+  let ParserMatchClass = Imm1_32Operand;
 }
 
 class fixedpoint_recip_i64<ValueType FloatVT>
@@ -890,6 +891,7 @@ class fixedpoint_recip_i64<ValueType FloatVT>
   let EncoderMethod = "getFixedPointScaleOpValue";
   let DecoderMethod = "DecodeFixedPointScaleImm64";
   let OperandType = "OPERAND_IMMEDIATE";
+  let ParserMatchClass = Imm1_64Operand;
 }
 
 def fixedpoint_recip_f16_i32 : fixedpoint_recip_i32<f16>;
@@ -7684,8 +7686,8 @@ multiclass SIMDWideThreeVectorBHS<bit U, bits<4> opc, string asm,
 //----------------------------------------------------------------------------
 
 class BaseSIMDBitwiseExtract<bit size, RegisterOperand regtype, ValueType vty,
-                             string asm, string kind>
-  : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, i32imm:$imm), asm,
+                             Operand immtype, string asm, string kind>
+  : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, immtype:$imm), asm,
       "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind # ", $imm" #
       "|" # kind # "\t$Rd, $Rn, $Rm, $imm}", "",
       [(set (vty regtype:$Rd),
@@ -7708,10 +7710,10 @@ class BaseSIMDBitwiseExtract<bit size, RegisterOperand regtype, ValueType vty,
 
 
 multiclass SIMDBitwiseExtract<string asm> {
-  def v8i8  : BaseSIMDBitwiseExtract<0, V64, v8i8, asm, ".8b"> {
+  def v8i8  : BaseSIMDBitwiseExtract<0, V64, v8i8, imm32_0_7, asm, ".8b"> {
     let imm{3} = 0;
   }
-  def v16i8 : BaseSIMDBitwiseExtract<1, V128, v16i8, asm, ".16b">;
+  def v16i8 : BaseSIMDBitwiseExtract<1, V128, v16i8, imm32_0_15, asm, ".16b">;
 }
 
 //----------------------------------------------------------------------------
diff --git a/llvm/test/MC/AArch64/arm64-diags.s b/llvm/test/MC/AArch64/arm64-diags.s
index bcd42d98cd5f3..3224051b8885a 100644
--- a/llvm/test/MC/AArch64/arm64-diags.s
+++ b/llvm/test/MC/AArch64/arm64-diags.s
@@ -144,6 +144,24 @@ ldr    q1, [x3, w3, sxtw #1]
 ; CHECK-ERRORS:   uqshrn2 v4.4s, v5.2d, #67
 ; CHECK-ERRORS:                         ^
 
+; Fixed-point conversion scale operands must be integer immediates.
+  scvtf s0, w0, f0
+  scvtf d0, w0, f0
+  ucvtf s0, w0, f0
+  ucvtf d0, x0, f0
+
+; CHECK-ERRORS: error: immediate must be an integer in range [1, 32].
+; CHECK-ERRORS:   scvtf s0, w0, f0
+; CHECK-ERRORS:                  ^
+; CHECK-ERRORS: error: immediate must be an integer in range [1, 32].
+; CHECK-ERRORS:   scvtf d0, w0, f0
+; CHECK-ERRORS:                  ^
+; CHECK-ERRORS: error: immediate must be an integer in range [1, 32].
+; CHECK-ERRORS:   ucvtf s0, w0, f0
+; CHECK-ERRORS:                  ^
+; CHECK-ERRORS: error: immediate must be an integer in range [1, 64].
+; CHECK-ERRORS:   ucvtf d0, x0, f0
+; CHECK-ERRORS:                  ^
 
   st1.s4 {v14, v15}, [x2], #32
 ; CHECK-ERRORS: error: invalid type suffix for instruction
diff --git a/llvm/test/MC/AArch64/neon-diagnostics.s b/llvm/test/MC/AArch64/neon-diagnostics.s
index 2610f4acf383b..989a8bbab4615 100644
--- a/llvm/test/MC/AArch64/neon-diagnostics.s
+++ b/llvm/test/MC/AArch64/neon-diagnostics.s
@@ -6418,6 +6418,15 @@
 // CHECK-ERROR:         ext v0.2d, v1.2d, v2.2d, #0x0
 // CHECK-ERROR:                ^
 
+        // Symbolic operands are not valid byte-index immediates.
+        ext v0.8b, v1.8b, v2.8b, f0
+// CHECK-ERROR: [[@LINE-1]]:34: error: immediate must be an integer in range [0, 7].
+        ext v0.16b, v1.16b, v2.16b, f0
+// CHECK-ERROR: [[@LINE-1]]:37: error: immediate must be an integer in range [0, 15].
+        ext v0.8b, v1.8b, v2.8b, NaN
+// CHECK-ERROR: [[@LINE-1]]:34: error: immediate must be an integer in range [0, 7].
+        ext v0.8b, v1.8b, v2.8b, Inf
+// CHECK-ERROR: [[@LINE-1]]:34: error: immediate must be an integer in range [0, 7].
 
 //----------------------------------------------------------------------
 // Permutation with 3 vectors



More information about the llvm-commits mailing list