Skip to content

[ARM] Reject fixed-point VCVT with different registers #126232

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 2 commits into from
Feb 7, 2025

Conversation

ostannard
Copy link
Collaborator

These instructions only have one register field in their encoding, so both registers in the assembly must be the same.

Previously, we were accepting these instructions, but ignoring the second register operand.

Fixes #126227

These instructions only have one register field in their encoding, so
both registers in the assembly must be the same.
@llvmbot llvmbot added the mc Machine (object) code label Feb 7, 2025
@llvmbot
Copy link
Member

llvmbot commented Feb 7, 2025

@llvm/pr-subscribers-mc

@llvm/pr-subscribers-backend-arm

Author: Oliver Stannard (ostannard)

Changes

These instructions only have one register field in their encoding, so both registers in the assembly must be the same.

Previously, we were accepting these instructions, but ignoring the second register operand.

Fixes #126227


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

2 Files Affected:

  • (modified) llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp (+31)
  • (added) llvm/test/MC/ARM/vcvt-fixed-point-errors.s (+51)
diff --git a/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp b/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
index dad91c6a969e879..325dfb33762a663 100644
--- a/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
+++ b/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
@@ -8652,6 +8652,37 @@ bool ARMAsmParser::validateInstruction(MCInst &Inst,
                    "coprocessor must be configured as GCP");
     break;
   }
+
+  case ARM::VTOSHH:
+  case ARM::VTOUHH:
+  case ARM::VTOSLH:
+  case ARM::VTOULH:
+  case ARM::VTOSHS:
+  case ARM::VTOUHS:
+  case ARM::VTOSLS:
+  case ARM::VTOULS:
+  case ARM::VTOSHD:
+  case ARM::VTOUHD:
+  case ARM::VTOSLD:
+  case ARM::VTOULD:
+  case ARM::VSHTOH:
+  case ARM::VUHTOH:
+  case ARM::VSLTOH:
+  case ARM::VULTOH:
+  case ARM::VSHTOS:
+  case ARM::VUHTOS:
+  case ARM::VSLTOS:
+  case ARM::VULTOS:
+  case ARM::VSHTOD:
+  case ARM::VUHTOD:
+  case ARM::VSLTOD:
+  case ARM::VULTOD: {
+    if (Operands[MnemonicOpsEndInd]->getReg() !=
+        Operands[MnemonicOpsEndInd + 1]->getReg())
+      return Error(Operands[MnemonicOpsEndInd]->getStartLoc(),
+                   "source and destination registers must be the same");
+    break;
+  }
   }
 
   return false;
diff --git a/llvm/test/MC/ARM/vcvt-fixed-point-errors.s b/llvm/test/MC/ARM/vcvt-fixed-point-errors.s
new file mode 100644
index 000000000000000..90e9da054a9081e
--- /dev/null
+++ b/llvm/test/MC/ARM/vcvt-fixed-point-errors.s
@@ -0,0 +1,51 @@
+// RUN: not llvm-mc -triple=armv8a-none-eabi -mattr=+fullfp16 < %s 2>&1 | FileCheck %s
+
+  vcvt.u16.f16 s0, s1, #1
+// CHECK: [[@LINE-1]]{{.*}}error: source and destination registers must be the same
+  vcvt.s16.f16 s0, s1, #1
+// CHECK: [[@LINE-1]]{{.*}}error: source and destination registers must be the same
+  vcvt.u32.f16 s0, s1, #1
+// CHECK: [[@LINE-1]]{{.*}}error: source and destination registers must be the same
+  vcvt.s32.f16 s0, s1, #1
+// CHECK: [[@LINE-1]]{{.*}}error: source and destination registers must be the same
+  vcvt.u16.f32 s0, s1, #1
+// CHECK: [[@LINE-1]]{{.*}}error: source and destination registers must be the same
+  vcvt.s16.f32 s0, s1, #1
+// CHECK: [[@LINE-1]]{{.*}}error: source and destination registers must be the same
+  vcvt.u32.f32 s0, s1, #1
+// CHECK: [[@LINE-1]]{{.*}}error: source and destination registers must be the same
+  vcvt.s32.f32 s0, s1, #1
+// CHECK: [[@LINE-1]]{{.*}}error: source and destination registers must be the same
+  vcvt.u16.f64 d0, d1, #1
+// CHECK: [[@LINE-1]]{{.*}}error: source and destination registers must be the same
+  vcvt.s16.f64 d0, d1, #1
+// CHECK: [[@LINE-1]]{{.*}}error: source and destination registers must be the same
+  vcvt.u32.f64 d0, d1, #1
+// CHECK: [[@LINE-1]]{{.*}}error: source and destination registers must be the same
+  vcvt.s32.f64 d0, d1, #1
+// CHECK: [[@LINE-1]]{{.*}}error: source and destination registers must be the same
+  vcvt.f16.u16 s0, s1, #1
+// CHECK: [[@LINE-1]]{{.*}}error: source and destination registers must be the same
+  vcvt.f16.s16 s0, s1, #1
+// CHECK: [[@LINE-1]]{{.*}}error: source and destination registers must be the same
+  vcvt.f16.u32 s0, s1, #1
+// CHECK: [[@LINE-1]]{{.*}}error: source and destination registers must be the same
+  vcvt.f16.s32 s0, s1, #1
+// CHECK: [[@LINE-1]]{{.*}}error: source and destination registers must be the same
+  vcvt.f32.u16 s0, s1, #1
+// CHECK: [[@LINE-1]]{{.*}}error: source and destination registers must be the same
+  vcvt.f32.s16 s0, s1, #1
+// CHECK: [[@LINE-1]]{{.*}}error: source and destination registers must be the same
+  vcvt.f32.u32 s0, s1, #1
+// CHECK: [[@LINE-1]]{{.*}}error: source and destination registers must be the same
+  vcvt.f32.s32 s0, s1, #1
+// CHECK: [[@LINE-1]]{{.*}}error: source and destination registers must be the same
+  vcvt.f64.u16 d0, d1, #1
+// CHECK: [[@LINE-1]]{{.*}}error: source and destination registers must be the same
+  vcvt.f64.s16 d0, d1, #1
+// CHECK: [[@LINE-1]]{{.*}}error: source and destination registers must be the same
+  vcvt.f64.u32 d0, d1, #1
+// CHECK: [[@LINE-1]]{{.*}}error: source and destination registers must be the same
+  vcvt.f64.s32 d0, d1, #1
+// CHECK: [[@LINE-1]]{{.*}}error: source and destination registers must be the same
+

Copy link
Contributor

@jthackray jthackray left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for this. LGTM.

Copy link
Contributor

@AlfieRichardsArm AlfieRichardsArm left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM too!

I did have a memory of Tablegen instruction records being able to contain a validation function which could have been a nicer way to do this but I cant find any record of that.

@ostannard
Copy link
Collaborator Author

The tablegen does have a way to mark two operands as being tied, but as far as I can tell that's only used for codegen, not assembly.

@ostannard ostannard merged commit 1f2c36a into llvm:main Feb 7, 2025
8 checks passed
Icohedron pushed a commit to Icohedron/llvm-project that referenced this pull request Feb 11, 2025
These instructions only have one register field in their encoding, so
both registers in the assembly must be the same.

Previously, we were accepting these instructions, but ignoring the
second register operand.

Fixes llvm#126227
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
backend:ARM mc Machine (object) code
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[ARM] Invalid invalid fixed-point conversion instructions accepted by assembler
4 participants