Skip to content

Conversation

@topperc
Copy link
Collaborator

@topperc topperc commented Jul 14, 2025

Instead of allowing a parsed MCInst to have a either uimm10 or simm10, always render as simm10. This avoids a mismatch between parsed MCInst and disassembled MCInst when a uimm10 value is used.

Instead of allowing a parsed MCInst to have a either uimm10 or
simm10, always render as simm10. This avoids a mismatch between
parsed MCInst and disassembled MCInst when a uimm10 value is used.
@topperc topperc requested review from lenary, realqhc and wangpc-pp July 14, 2025 23:26
@llvmbot llvmbot added backend:RISC-V llvm:mc Machine (object) code labels Jul 14, 2025
@llvmbot
Copy link
Member

llvmbot commented Jul 14, 2025

@llvm/pr-subscribers-backend-risc-v

Author: Craig Topper (topperc)

Changes

Instead of allowing a parsed MCInst to have a either uimm10 or simm10, always render as simm10. This avoids a mismatch between parsed MCInst and disassembled MCInst when a uimm10 value is used.


Full diff: https://github.com/llvm/llvm-project/pull/148749.diff

5 Files Affected:

  • (modified) llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp (+8)
  • (modified) llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h (-1)
  • (modified) llvm/lib/Target/RISCV/RISCVInstrInfoP.td (+7-3)
  • (modified) llvm/test/MC/RISCV/rv32p-valid.s (+2-3)
  • (modified) llvm/test/MC/RISCV/rv64p-valid.s (+3-5)
diff --git a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
index 66f4aade380fa..b6bb5549985b2 100644
--- a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
+++ b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
@@ -1199,6 +1199,14 @@ struct RISCVOperand final : public MCParsedAsmOperand {
     addExpr(Inst, getImm(), isRV64Imm());
   }
 
+  void addSImm10UnsignedOperands(MCInst &Inst, unsigned N) const {
+    assert(N == 1 && "Invalid number of operands!");
+    int64_t Imm;
+    [[maybe_unused]] bool IsConstant = evaluateConstantImm(getImm(), Imm);
+    assert(IsConstant);
+    Inst.addOperand(MCOperand::createImm(SignExtend64<10>(Imm)));
+  }
+
   void addFPImmOperands(MCInst &Inst, unsigned N) const {
     assert(N == 1 && "Invalid number of operands!");
     if (isImm()) {
diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h
index f41ad419db1a7..4c8dcf376755b 100644
--- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h
+++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h
@@ -339,7 +339,6 @@ enum OperandType : unsigned {
   OPERAND_SIMM6,
   OPERAND_SIMM6_NONZERO,
   OPERAND_SIMM10,
-  OPERAND_SIMM10_UNSIGNED,
   OPERAND_SIMM10_LSB0000_NONZERO,
   OPERAND_SIMM11,
   OPERAND_SIMM12,
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoP.td b/llvm/lib/Target/RISCV/RISCVInstrInfoP.td
index aa9e7b5635def..830cd27632102 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfoP.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfoP.td
@@ -20,18 +20,22 @@
 
 def simm10 : RISCVSImmLeafOp<10>;
 
+def SImm10UnsignedAsmOperand : SImmAsmOperand<10, "Unsigned"> {
+  let RenderMethod = "addSImm10UnsignedOperands";
+}
+
 // A 10-bit signed immediate allowing range [-512, 1023]
 // but will decode to [-512, 511].
 def simm10_unsigned : RISCVOp {
-  let ParserMatchClass = SImmAsmOperand<10, "Unsigned">;
+  let ParserMatchClass = SImm10UnsignedAsmOperand;
   let EncoderMethod = "getImmOpValue";
   let DecoderMethod = "decodeSImmOperand<10>";
-  let OperandType = "OPERAND_SIMM10_UNSIGNED";
+  let OperandType = "OPERAND_SIMM10";
   let MCOperandPredicate = [{
     int64_t Imm;
     if (!MCOp.evaluateAsConstantImm(Imm))
       return false;
-    return isInt<10>(Imm) || isUInt<10>(Imm);
+    return isInt<10>(Imm);
   }];
 }
 
diff --git a/llvm/test/MC/RISCV/rv32p-valid.s b/llvm/test/MC/RISCV/rv32p-valid.s
index c755acddc712e..c259c142f92b2 100644
--- a/llvm/test/MC/RISCV/rv32p-valid.s
+++ b/llvm/test/MC/RISCV/rv32p-valid.s
@@ -2,7 +2,7 @@
 # RUN:     | FileCheck -check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ %s
 # RUN: llvm-mc -filetype=obj -triple=riscv32 -mattr=+experimental-p < %s \
 # RUN:     | llvm-objdump --mattr=+experimental-p -M no-aliases -d -r --no-print-imm-hex - \
-# RUN:     | FileCheck --check-prefixes=CHECK-ASM-AND-OBJ,CHECK-OBJ %s
+# RUN:     | FileCheck --check-prefixes=CHECK-ASM-AND-OBJ %s
 
 # CHECK-ASM-AND-OBJ: clz a0, a1
 # CHECK-ASM: encoding: [0x13,0x95,0x05,0x60]
@@ -73,7 +73,6 @@ psabs.b t0, t1
 # CHECK-ASM-AND-OBJ: plui.h gp, 32
 # CHECK-ASM: encoding: [0x9b,0x21,0x20,0xf0]
 plui.h gp, 32
-# CHECK-OBJ: plui.h gp, -412
-# CHECK-ASM: plui.h gp, 612
+# CHECK-ASM-AND-OBJ: plui.h gp, -412
 # CHECK-ASM: encoding: [0x9b,0xa1,0x64,0xf0]
 plui.h gp, 612
diff --git a/llvm/test/MC/RISCV/rv64p-valid.s b/llvm/test/MC/RISCV/rv64p-valid.s
index 6c48ad3469b47..3ea6b00bbe11c 100644
--- a/llvm/test/MC/RISCV/rv64p-valid.s
+++ b/llvm/test/MC/RISCV/rv64p-valid.s
@@ -2,7 +2,7 @@
 # RUN:     | FileCheck -check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ %s
 # RUN: llvm-mc -filetype=obj --triple=riscv64 -mattr=+experimental-p < %s \
 # RUN:     | llvm-objdump --triple=riscv64 --mattr=+experimental-p -M no-aliases --no-print-imm-hex -d -r - \
-# RUN:     | FileCheck --check-prefixes=CHECK-ASM-AND-OBJ,CHECK-OBJ %s
+# RUN:     | FileCheck --check-prefixes=CHECK-ASM-AND-OBJ %s
 
 # CHECK-ASM-AND-OBJ: clz a0, a1
 # CHECK-ASM: encoding: [0x13,0x95,0x05,0x60]
@@ -97,14 +97,12 @@ psabs.b a0, s2
 # CHECK-ASM-AND-OBJ: plui.h s2, 4
 # CHECK-ASM: encoding: [0x1b,0x29,0x04,0xf0]
 plui.h s2, 4
-# CHECK-OBJ: plui.h gp, -412
-# CHECK-ASM: plui.h gp, 612
+# CHECK-ASM-AND-OBJ: plui.h gp, -412
 # CHECK-ASM: encoding: [0x9b,0xa1,0x64,0xf0]
 plui.h gp, 612
 # CHECK-ASM-AND-OBJ: plui.w a2, 1
 # CHECK-ASM: encoding: [0x1b,0x26,0x01,0xf2]
 plui.w a2, 1
-# CHECK-OBJ: plui.w a2, -1
-# CHECK-ASM: plui.w a2, 1023
+# CHECK-ASM-AND-OBJ: plui.w a2, -1
 # CHECK-ASM: encoding: [0x1b,0xa6,0xff,0xf3]
 plui.w a2, 1023

@llvmbot
Copy link
Member

llvmbot commented Jul 14, 2025

@llvm/pr-subscribers-mc

Author: Craig Topper (topperc)

Changes

Instead of allowing a parsed MCInst to have a either uimm10 or simm10, always render as simm10. This avoids a mismatch between parsed MCInst and disassembled MCInst when a uimm10 value is used.


Full diff: https://github.com/llvm/llvm-project/pull/148749.diff

5 Files Affected:

  • (modified) llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp (+8)
  • (modified) llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h (-1)
  • (modified) llvm/lib/Target/RISCV/RISCVInstrInfoP.td (+7-3)
  • (modified) llvm/test/MC/RISCV/rv32p-valid.s (+2-3)
  • (modified) llvm/test/MC/RISCV/rv64p-valid.s (+3-5)
diff --git a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
index 66f4aade380fa..b6bb5549985b2 100644
--- a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
+++ b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
@@ -1199,6 +1199,14 @@ struct RISCVOperand final : public MCParsedAsmOperand {
     addExpr(Inst, getImm(), isRV64Imm());
   }
 
+  void addSImm10UnsignedOperands(MCInst &Inst, unsigned N) const {
+    assert(N == 1 && "Invalid number of operands!");
+    int64_t Imm;
+    [[maybe_unused]] bool IsConstant = evaluateConstantImm(getImm(), Imm);
+    assert(IsConstant);
+    Inst.addOperand(MCOperand::createImm(SignExtend64<10>(Imm)));
+  }
+
   void addFPImmOperands(MCInst &Inst, unsigned N) const {
     assert(N == 1 && "Invalid number of operands!");
     if (isImm()) {
diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h
index f41ad419db1a7..4c8dcf376755b 100644
--- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h
+++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h
@@ -339,7 +339,6 @@ enum OperandType : unsigned {
   OPERAND_SIMM6,
   OPERAND_SIMM6_NONZERO,
   OPERAND_SIMM10,
-  OPERAND_SIMM10_UNSIGNED,
   OPERAND_SIMM10_LSB0000_NONZERO,
   OPERAND_SIMM11,
   OPERAND_SIMM12,
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoP.td b/llvm/lib/Target/RISCV/RISCVInstrInfoP.td
index aa9e7b5635def..830cd27632102 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfoP.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfoP.td
@@ -20,18 +20,22 @@
 
 def simm10 : RISCVSImmLeafOp<10>;
 
+def SImm10UnsignedAsmOperand : SImmAsmOperand<10, "Unsigned"> {
+  let RenderMethod = "addSImm10UnsignedOperands";
+}
+
 // A 10-bit signed immediate allowing range [-512, 1023]
 // but will decode to [-512, 511].
 def simm10_unsigned : RISCVOp {
-  let ParserMatchClass = SImmAsmOperand<10, "Unsigned">;
+  let ParserMatchClass = SImm10UnsignedAsmOperand;
   let EncoderMethod = "getImmOpValue";
   let DecoderMethod = "decodeSImmOperand<10>";
-  let OperandType = "OPERAND_SIMM10_UNSIGNED";
+  let OperandType = "OPERAND_SIMM10";
   let MCOperandPredicate = [{
     int64_t Imm;
     if (!MCOp.evaluateAsConstantImm(Imm))
       return false;
-    return isInt<10>(Imm) || isUInt<10>(Imm);
+    return isInt<10>(Imm);
   }];
 }
 
diff --git a/llvm/test/MC/RISCV/rv32p-valid.s b/llvm/test/MC/RISCV/rv32p-valid.s
index c755acddc712e..c259c142f92b2 100644
--- a/llvm/test/MC/RISCV/rv32p-valid.s
+++ b/llvm/test/MC/RISCV/rv32p-valid.s
@@ -2,7 +2,7 @@
 # RUN:     | FileCheck -check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ %s
 # RUN: llvm-mc -filetype=obj -triple=riscv32 -mattr=+experimental-p < %s \
 # RUN:     | llvm-objdump --mattr=+experimental-p -M no-aliases -d -r --no-print-imm-hex - \
-# RUN:     | FileCheck --check-prefixes=CHECK-ASM-AND-OBJ,CHECK-OBJ %s
+# RUN:     | FileCheck --check-prefixes=CHECK-ASM-AND-OBJ %s
 
 # CHECK-ASM-AND-OBJ: clz a0, a1
 # CHECK-ASM: encoding: [0x13,0x95,0x05,0x60]
@@ -73,7 +73,6 @@ psabs.b t0, t1
 # CHECK-ASM-AND-OBJ: plui.h gp, 32
 # CHECK-ASM: encoding: [0x9b,0x21,0x20,0xf0]
 plui.h gp, 32
-# CHECK-OBJ: plui.h gp, -412
-# CHECK-ASM: plui.h gp, 612
+# CHECK-ASM-AND-OBJ: plui.h gp, -412
 # CHECK-ASM: encoding: [0x9b,0xa1,0x64,0xf0]
 plui.h gp, 612
diff --git a/llvm/test/MC/RISCV/rv64p-valid.s b/llvm/test/MC/RISCV/rv64p-valid.s
index 6c48ad3469b47..3ea6b00bbe11c 100644
--- a/llvm/test/MC/RISCV/rv64p-valid.s
+++ b/llvm/test/MC/RISCV/rv64p-valid.s
@@ -2,7 +2,7 @@
 # RUN:     | FileCheck -check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ %s
 # RUN: llvm-mc -filetype=obj --triple=riscv64 -mattr=+experimental-p < %s \
 # RUN:     | llvm-objdump --triple=riscv64 --mattr=+experimental-p -M no-aliases --no-print-imm-hex -d -r - \
-# RUN:     | FileCheck --check-prefixes=CHECK-ASM-AND-OBJ,CHECK-OBJ %s
+# RUN:     | FileCheck --check-prefixes=CHECK-ASM-AND-OBJ %s
 
 # CHECK-ASM-AND-OBJ: clz a0, a1
 # CHECK-ASM: encoding: [0x13,0x95,0x05,0x60]
@@ -97,14 +97,12 @@ psabs.b a0, s2
 # CHECK-ASM-AND-OBJ: plui.h s2, 4
 # CHECK-ASM: encoding: [0x1b,0x29,0x04,0xf0]
 plui.h s2, 4
-# CHECK-OBJ: plui.h gp, -412
-# CHECK-ASM: plui.h gp, 612
+# CHECK-ASM-AND-OBJ: plui.h gp, -412
 # CHECK-ASM: encoding: [0x9b,0xa1,0x64,0xf0]
 plui.h gp, 612
 # CHECK-ASM-AND-OBJ: plui.w a2, 1
 # CHECK-ASM: encoding: [0x1b,0x26,0x01,0xf2]
 plui.w a2, 1
-# CHECK-OBJ: plui.w a2, -1
-# CHECK-ASM: plui.w a2, 1023
+# CHECK-ASM-AND-OBJ: plui.w a2, -1
 # CHECK-ASM: encoding: [0x1b,0xa6,0xff,0xf3]
 plui.w a2, 1023

@topperc topperc merged commit 31944ac into llvm:main Jul 15, 2025
9 checks passed
@topperc topperc deleted the pr/simm10_unsigned branch July 15, 2025 03:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

backend:RISC-V llvm:mc Machine (object) code

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants