Skip to content

[RISCV] Validate the end of register ranges in Zcmp register lists. #133866

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Apr 1, 2025

Conversation

topperc
Copy link
Collaborator

@topperc topperc commented Apr 1, 2025

We were only checking that the last register was a register, not that it was a legal register for a register list. This caused the encoder function to hit an llvm_unreachable.

The error messages are not good, but this only one of multiple things that need to be fixed in this function. I'll focus on error messages later once I have the other issues fixed.

We were only checking that the last register was a register, not
that it was a legal register for a register list. This caused the
encoder function to hit an llvm_unreachable.

The error messages are not good, but this only one of multiple things
that need to be fixed in this function. I'll focus on error messages
later once I have the other issues fixed.
@topperc topperc requested a review from lenary April 1, 2025 06:11
@llvmbot llvmbot added backend:RISC-V mc Machine (object) code labels Apr 1, 2025
@llvmbot
Copy link
Member

llvmbot commented Apr 1, 2025

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

@llvm/pr-subscribers-mc

Author: Craig Topper (topperc)

Changes

We were only checking that the last register was a register, not that it was a legal register for a register list. This caused the encoder function to hit an llvm_unreachable.

The error messages are not good, but this only one of multiple things that need to be fixed in this function. I'll focus on error messages later once I have the other issues fixed.


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

3 Files Affected:

  • (modified) llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp (+3-2)
  • (modified) llvm/test/MC/RISCV/rv32zcmp-invalid.s (+20-2)
  • (modified) llvm/test/MC/RISCV/rv64zcmp-invalid.s (+21)
diff --git a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
index c1670326143e3..f12122c05b32d 100644
--- a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
+++ b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
@@ -2616,7 +2616,8 @@ ParseStatus RISCVAsmParser::parseRegListCommon(OperandVector &Operands,
     StringRef EndName = getLexer().getTok().getIdentifier();
     // FIXME: the register mapping and checks of EABI is wrong
     RegEnd = matchRegisterNameHelper(EndName);
-    if (!RegEnd)
+    if (!(RegEnd == RISCV::X9 ||
+          (RegEnd >= RISCV::X18 && RegEnd <= RISCV::X27)))
       return Error(getLoc(), "invalid register");
     if (IsEABI && RegEnd != RISCV::X9)
       return Error(getLoc(), "contiguous register list of EABI can only be "
@@ -2649,7 +2650,7 @@ ParseStatus RISCVAsmParser::parseRegListCommon(OperandVector &Operands,
           return Error(getLoc(), "invalid register");
         EndName = getLexer().getTok().getIdentifier();
         RegEnd = MatchRegisterName(EndName);
-        if (!RegEnd)
+        if (!(RegEnd >= RISCV::X19 && RegEnd <= RISCV::X27))
           return Error(getLoc(), "invalid register");
         getLexer().Lex();
       }
diff --git a/llvm/test/MC/RISCV/rv32zcmp-invalid.s b/llvm/test/MC/RISCV/rv32zcmp-invalid.s
index 4115333fc738b..f89829a33bd9e 100644
--- a/llvm/test/MC/RISCV/rv32zcmp-invalid.s
+++ b/llvm/test/MC/RISCV/rv32zcmp-invalid.s
@@ -25,5 +25,23 @@ cm.pop {ra, s0-s1}, -32
 # CHECK-ERROR: error: stack adjustment for register list must be a multiple of 16 bytes in the range [-64, -16]
 cm.push {ra}, -8
 
-# CHECK-ERROR: error: stack adjustment for register list must be a multiple of 16 bytes in the range [16, 64]
-cm.pop {ra, s0-s1}, -40
+# CHECK-ERROR: :[[@LINE+1]]:9: error: register list must start from 'ra' or 'x1'
+cm.pop {s0}, -40
+
+# CHECK-ERROR: :[[@LINE+1]]:13: error: continuous register list must start from 's0' or 'x8'
+cm.pop {ra, t1}, -40
+
+# CHECK-ERROR: :[[@LINE+1]]:16: error: invalid register
+cm.pop {ra, s0-t1}, -40
+
+# CHECK-ERROR: :[[@LINE+1]]:20: error: second contiguous registers pair of register list must start from 'x18'
+cm.pop {ra, x8-x9, x28}, -40
+
+# CHECK-ERROR: :[[@LINE+1]]:24: error: invalid register
+cm.pop {ra, x8-x9, x18-x28}, -40
+
+# CHECK-ERROR: :[[@LINE+1]]:24: error: invalid register
+cm.pop {ra, x8-x9, x18-x17}, -40
+
+# CHECK-ERROR: :[[@LINE+1]]:16: error: invalid register
+cm.pop {ra, x8-f8, x18-x17}, -40
diff --git a/llvm/test/MC/RISCV/rv64zcmp-invalid.s b/llvm/test/MC/RISCV/rv64zcmp-invalid.s
index 804234d2c11e6..7f90bf73ac713 100644
--- a/llvm/test/MC/RISCV/rv64zcmp-invalid.s
+++ b/llvm/test/MC/RISCV/rv64zcmp-invalid.s
@@ -27,3 +27,24 @@ cm.push {ra}, -15
 
 # CHECK-ERROR: error: stack adjustment for register list must be a multiple of 16 bytes in the range [32, 80]
 cm.pop {ra, s0-s1}, -33
+
+# CHECK-ERROR: :[[@LINE+1]]:9: error: register list must start from 'ra' or 'x1'
+cm.pop {s0}, -40
+
+# CHECK-ERROR: :[[@LINE+1]]:13: error: continuous register list must start from 's0' or 'x8'
+cm.pop {ra, t1}, -40
+
+# CHECK-ERROR: :[[@LINE+1]]:16: error: invalid register
+cm.pop {ra, s0-t1}, -40
+
+# CHECK-ERROR: :[[@LINE+1]]:20: error: second contiguous registers pair of register list must start from 'x18'
+cm.pop {ra, x8-x9, x28}, -40
+
+# CHECK-ERROR: :[[@LINE+1]]:24: error: invalid register
+cm.pop {ra, x8-x9, x18-x28}, -40
+
+# CHECK-ERROR: :[[@LINE+1]]:24: error: invalid register
+cm.pop {ra, x8-x9, x18-x17}, -40
+
+# CHECK-ERROR: :[[@LINE+1]]:16: error: invalid register
+cm.pop {ra, x8-f8, x18-x17}, -40

@topperc topperc merged commit 19fb4b0 into llvm:main Apr 1, 2025
14 checks passed
@topperc topperc deleted the pr/zcmp-bad-register branch April 1, 2025 15:04
Ankur-0429 pushed a commit to Ankur-0429/llvm-project that referenced this pull request Apr 2, 2025
…lvm#133866)

We were only checking that the last register was a register, not that it
was a legal register for a register list. This caused the encoder
function to hit an llvm_unreachable.

The error messages are not good, but this only one of multiple things
that need to be fixed in this function. I'll focus on error messages
later once I have the other issues fixed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
backend:RISC-V mc Machine (object) code
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants