[llvm] [AArch64] Validate fixed-point SCVTF/UCVTF scale operands (PR #213490)

Shuvam Pandey via llvm-commits llvm-commits at lists.llvm.org
Sat Aug 1 14:46:50 PDT 2026


https://github.com/shuv-amp created https://github.com/llvm/llvm-project/pull/213490

The fixed-point SCVTF/UCVTF operands are missing the ParserMatchClass used by
fixedpoint_i32/i64. Symbolic scales can therefore reach the encoder and hit
its MO.isImm() assertion, while out-of-range scales can alias valid encodings.

Use Imm1_32Operand and Imm1_64Operand for these operands and add diagnostics
for both source widths and symbolic scales.

Addresses the scvtf/ucvtf part of #185358. The ext case is tracked by #185361.

>From 3fc49e8522018965ed7cc2cf2242917c30822ccd Mon Sep 17 00:00:00 2001
From: Shuvam Pandey <shuvampandey1 at gmail.com>
Date: Sun, 2 Aug 2026 03:15:55 +0545
Subject: [PATCH] [AArch64] Validate fixed-point SCVTF/UCVTF scale operands

When 9f8dcb070655 moved the scaled SCVTF/UCVTF forms to the
fixedpoint_recip operands, the new operands did not carry over the
ParserMatchClass used by fixedpoint_i32/i64. Symbolic scales can then
reach the encoder and fail its MO.isImm() assertion, while out-of-range
constants can alias valid encodings.

Use Imm1_32Operand and Imm1_64Operand for the reciprocal operands and
add diagnostics for both source widths and symbolic scales.

Addresses the scvtf/ucvtf part of #185358. The ext case is tracked by
#185361.
---
 .../lib/Target/AArch64/AArch64InstrFormats.td |  2 +
 llvm/test/MC/AArch64/basic-a64-diagnostics.s  | 37 +++++++++++++++++++
 2 files changed, 39 insertions(+)

diff --git a/llvm/lib/Target/AArch64/AArch64InstrFormats.td b/llvm/lib/Target/AArch64/AArch64InstrFormats.td
index 30d7c291ca4d4..0e6e28d1cbb0e 100644
--- a/llvm/lib/Target/AArch64/AArch64InstrFormats.td
+++ b/llvm/lib/Target/AArch64/AArch64InstrFormats.td
@@ -881,6 +881,7 @@ class fixedpoint_recip_i32<ValueType FloatVT>
     ComplexPattern<FloatVT, 1, "SelectCVTFixedPosRecipOperand<32>", [fpimm, ld]> {
   let EncoderMethod = "getFixedPointScaleOpValue";
   let DecoderMethod = "DecodeFixedPointScaleImm32";
+  let ParserMatchClass = Imm1_32Operand;
   let OperandType = "OPERAND_IMMEDIATE";
 }
 
@@ -889,6 +890,7 @@ class fixedpoint_recip_i64<ValueType FloatVT>
     ComplexPattern<FloatVT, 1, "SelectCVTFixedPosRecipOperand<64>", [fpimm, ld]> {
   let EncoderMethod = "getFixedPointScaleOpValue";
   let DecoderMethod = "DecodeFixedPointScaleImm64";
+  let ParserMatchClass = Imm1_64Operand;
   let OperandType = "OPERAND_IMMEDIATE";
 }
 
diff --git a/llvm/test/MC/AArch64/basic-a64-diagnostics.s b/llvm/test/MC/AArch64/basic-a64-diagnostics.s
index 028700f4d11df..823a37dc54f2c 100644
--- a/llvm/test/MC/AArch64/basic-a64-diagnostics.s
+++ b/llvm/test/MC/AArch64/basic-a64-diagnostics.s
@@ -1792,6 +1792,43 @@ cbz w1, lsl
 // CHECK-ERROR-NEXT:        ucvtf sp, s19, #14
 // CHECK-ERROR-NEXT:              ^
 
+// Scale range depends on the integer source: [1, 32] for Wn, [1, 64] for Xn
+        scvtf s0, w0, #0
+        scvtf s0, w0, #33
+        ucvtf s0, w0, #33
+// CHECK-ERROR-NEXT: error: immediate must be an integer in range [1, 32]
+// CHECK-ERROR-NEXT:        scvtf s0, w0, #0
+// CHECK-ERROR-NEXT:                      ^
+// CHECK-ERROR-NEXT: error: immediate must be an integer in range [1, 32]
+// CHECK-ERROR-NEXT:        scvtf s0, w0, #33
+// CHECK-ERROR-NEXT:                      ^
+// CHECK-ERROR-NEXT: error: immediate must be an integer in range [1, 32]
+// CHECK-ERROR-NEXT:        ucvtf s0, w0, #33
+// CHECK-ERROR-NEXT:                      ^
+
+        scvtf d0, x0, #0
+        scvtf d0, x0, #65
+        ucvtf d0, x0, #65
+// CHECK-ERROR-NEXT: error: immediate must be an integer in range [1, 64]
+// CHECK-ERROR-NEXT:        scvtf d0, x0, #0
+// CHECK-ERROR-NEXT:                      ^
+// CHECK-ERROR-NEXT: error: immediate must be an integer in range [1, 64]
+// CHECK-ERROR-NEXT:        scvtf d0, x0, #65
+// CHECK-ERROR-NEXT:                      ^
+// CHECK-ERROR-NEXT: error: immediate must be an integer in range [1, 64]
+// CHECK-ERROR-NEXT:        ucvtf d0, x0, #65
+// CHECK-ERROR-NEXT:                      ^
+
+// Scale must be an immediate, not a symbol
+        scvtf s0, w0, f0
+        ucvtf d0, x0, f0
+// CHECK-ERROR-NEXT: error: immediate must be an integer in range [1, 32]
+// CHECK-ERROR-NEXT:        scvtf s0, w0, f0
+// CHECK-ERROR-NEXT:                      ^
+// CHECK-ERROR-NEXT: error: immediate must be an integer in range [1, 64]
+// CHECK-ERROR-NEXT:        ucvtf d0, x0, f0
+// CHECK-ERROR-NEXT:                      ^
+
 //------------------------------------------------------------------------------
 // Floating-point immediate
 //------------------------------------------------------------------------------



More information about the llvm-commits mailing list