[llvm] [AMDGPU] Validate forced lit64() on VOP3 instructions (PR #196171)

Stanislav Mekhanoshin via llvm-commits llvm-commits at lists.llvm.org
Wed May 6 13:54:55 PDT 2026


https://github.com/rampitec updated https://github.com/llvm/llvm-project/pull/196171

>From 7cac1336b51f1f2d307454589455ae02a8e5eafd Mon Sep 17 00:00:00 2001
From: Stanislav Mekhanoshin <Stanislav.Mekhanoshin at amd.com>
Date: Wed, 6 May 2026 13:14:00 -0700
Subject: [PATCH] [AMDGPU] Validate forced lit64() on VOP3 instructions

Lit64 cannot be used with VOP3* but we did not validate it
in case it can be encoded as lit32, but forced with the
operand modifier.
---
 .../AMDGPU/AsmParser/AMDGPUAsmParser.cpp      | 33 ++++++++++++++-----
 llvm/test/MC/AMDGPU/gfx1250_asm_vop3_err.s    |  5 +++
 2 files changed, 30 insertions(+), 8 deletions(-)

diff --git a/llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp b/llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp
index 7b5738845ef2c..8922a2d752935 100644
--- a/llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp
+++ b/llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp
@@ -85,6 +85,7 @@ class AMDGPUOperand : public MCParsedAsmOperand {
     bool hasFPModifiers() const { return Abs || Neg; }
     bool hasIntModifiers() const { return Sext; }
     bool hasModifiers() const { return hasFPModifiers() || hasIntModifiers(); }
+    bool isForcedLit64() const { return Lit == LitModifier::Lit64; }
 
     int64_t getFPModifiersOperand() const {
       int64_t Operand = 0;
@@ -1051,6 +1052,10 @@ class AMDGPUOperand : public MCParsedAsmOperand {
     return getModifiers().hasIntModifiers();
   }
 
+  bool isForcedLit64() const {
+    return getModifiers().isForcedLit64();
+  }
+
   uint64_t applyInputFPModifiers(uint64_t Val, unsigned Size) const;
 
   void addImmOperands(MCInst &Inst, unsigned N, bool ApplyModifiers = true) const;
@@ -1827,6 +1832,9 @@ class AMDGPUAsmParser : public MCTargetAsmParser {
   ParseStatus parseHwregFunc(OperandInfoTy &HwReg, OperandInfoTy &Offset,
                              OperandInfoTy &Width);
 
+  const AMDGPUOperand &findMCOperand(const OperandVector &Operands,
+                                     int MCOpIdx) const;
+
   static SMLoc getLaterLoc(SMLoc a, SMLoc b);
 
   SMLoc getFlatOffsetLoc(const OperandVector &Operands) const;
@@ -5132,9 +5140,12 @@ bool AMDGPUAsmParser::validateVOPLiteral(const MCInst &Inst,
       bool IsFP64 = (IsForcedFP64 || AMDGPU::isSISrcFPOperand(Desc, OpIdx)) &&
                     AMDGPU::getOperandSize(Desc.operands()[OpIdx]) == 8;
       bool IsValid32Op = AMDGPU::isValid32BitLiteral(Value, IsFP64);
+      bool IsForcedLit64 = findMCOperand(Operands, OpIdx).isForcedLit64();
 
-      if (!IsValid32Op && !isInt<32>(Value) && !isUInt<32>(Value) &&
-          !IsForcedFP64 && (!has64BitLiterals() || Desc.getSize() != 4)) {
+      if (((!IsValid32Op && !isInt<32>(Value) && !isUInt<32>(Value) &&
+            !IsForcedFP64) ||
+           (IsForcedLit64 && !HasMandatoryLiteral)) &&
+          (!has64BitLiterals() || Desc.getSize() != 4)) {
         Error(getOperandLoc(Operands, OpIdx),
               "invalid operand for instruction");
         return false;
@@ -8559,6 +8570,17 @@ AMDGPUAsmParser::lex() {
   Parser.Lex();
 }
 
+const AMDGPUOperand &
+AMDGPUAsmParser::findMCOperand(const OperandVector &Operands,
+                               int MCOpIdx) const {
+  for (const auto &Op : Operands) {
+    const AMDGPUOperand &TargetOp = static_cast<AMDGPUOperand &>(*Op);
+    if (TargetOp.getMCOpIdx() == MCOpIdx)
+      return TargetOp;
+  }
+  llvm_unreachable("no such MC operand!");
+}
+
 SMLoc AMDGPUAsmParser::getInstLoc(const OperandVector &Operands) const {
   return ((AMDGPUOperand &)*Operands[0]).getStartLoc();
 }
@@ -8570,12 +8592,7 @@ SMLoc AMDGPUAsmParser::getLaterLoc(SMLoc a, SMLoc b) {
 
 SMLoc AMDGPUAsmParser::getOperandLoc(const OperandVector &Operands,
                                      int MCOpIdx) const {
-  for (const auto &Op : Operands) {
-    const auto TargetOp = static_cast<AMDGPUOperand &>(*Op);
-    if (TargetOp.getMCOpIdx() == MCOpIdx)
-      return TargetOp.getStartLoc();
-  }
-  llvm_unreachable("No such MC operand!");
+  return findMCOperand(Operands, MCOpIdx).getStartLoc();
 }
 
 SMLoc
diff --git a/llvm/test/MC/AMDGPU/gfx1250_asm_vop3_err.s b/llvm/test/MC/AMDGPU/gfx1250_asm_vop3_err.s
index 28e2e88c8b36d..fe39c861e5d39 100644
--- a/llvm/test/MC/AMDGPU/gfx1250_asm_vop3_err.s
+++ b/llvm/test/MC/AMDGPU/gfx1250_asm_vop3_err.s
@@ -327,3 +327,8 @@ v_cvt_scale_pk16_bf16_bf6 v[10:17], s[20:22], 0xcf00
 // GFX125X-ERR: :[[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
 // GFX125X-ERR-NEXT:{{^}}v_cvt_scale_pk16_bf16_bf6 v[10:17], s[20:22], 0xcf00
 // GFX125X-ERR-NEXT:{{^}}                                    ^
+
+v_add_f64_e64 v[4:5], lit64(101.0), v[8:9]
+// GFX125X-ERR: :[[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
+// GFX125X-ERR-NEXT:{{^}}v_add_f64_e64 v[4:5], lit64(101.0), v[8:9]
+// GFX125X-ERR-NEXT:{{^}}                            ^



More information about the llvm-commits mailing list