[llvm] [ms] [llvm-ml] Allow PTR casting of registers to their own size (PR #132751)
Eric Astor via llvm-commits
llvm-commits at lists.llvm.org
Mon Sep 8 07:06:06 PDT 2025
https://github.com/ericastor updated https://github.com/llvm/llvm-project/pull/132751
>From 0d0c008ddc48ec05e3da1e037ba240343658e9fc Mon Sep 17 00:00:00 2001
From: Eric Astor <epastor at google.com>
Date: Mon, 24 Mar 2025 14:50:14 +0000
Subject: [PATCH 01/11] [ms] [llvm-ml] Allow PTR casting of registers to their
own size
MASM allows no-op casts on register operands; for example, `DWORD PTR eax` is a legal expression. Any other cast is an error.
Fixes #132084
---
.../lib/Target/X86/AsmParser/X86AsmParser.cpp | 56 +++++++++++++++++--
llvm/test/tools/llvm-ml/cast.asm | 25 +++++++++
llvm/test/tools/llvm-ml/cast_errors.asm | 41 ++++++++++++++
3 files changed, 116 insertions(+), 6 deletions(-)
create mode 100644 llvm/test/tools/llvm-ml/cast.asm
create mode 100644 llvm/test/tools/llvm-ml/cast_errors.asm
diff --git a/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp b/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp
index a6285a55f4155..475b0016ace68 100644
--- a/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp
+++ b/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp
@@ -14,6 +14,9 @@
#include "MCTargetDesc/X86TargetStreamer.h"
#include "TargetInfo/X86TargetInfo.h"
#include "X86Operand.h"
+#include "third_party/llvm/llvm-project/llvm/include/llvm/ADT/StringRef.h"
+#include "third_party/llvm/llvm-project/llvm/include/llvm/MC/MCRegister.h"
+#include "third_party/llvm/llvm-project/llvm/lib/Target/X86/X86RegisterInfo.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/SmallVector.h"
@@ -38,6 +41,7 @@
#include "llvm/Support/SourceMgr.h"
#include "llvm/Support/raw_ostream.h"
#include <algorithm>
+#include <cstdint>
#include <memory>
using namespace llvm;
@@ -1150,7 +1154,7 @@ class X86AsmParser : public MCTargetAsmParser {
X86::CondCode ParseConditionCode(StringRef CCode);
- bool ParseIntelMemoryOperandSize(unsigned &Size);
+ bool ParseIntelMemoryOperandSize(unsigned &Size, StringRef *SizeStr);
bool CreateMemForMSInlineAsm(MCRegister SegReg, const MCExpr *Disp,
MCRegister BaseReg, MCRegister IndexReg,
unsigned Scale, bool NonAbsMem, SMLoc Start,
@@ -2551,7 +2555,8 @@ bool X86AsmParser::ParseMasmOperator(unsigned OpKind, int64_t &Val) {
return false;
}
-bool X86AsmParser::ParseIntelMemoryOperandSize(unsigned &Size) {
+bool X86AsmParser::ParseIntelMemoryOperandSize(unsigned &Size,
+ StringRef *SizeStr) {
Size = StringSwitch<unsigned>(getTok().getString())
.Cases("BYTE", "byte", 8)
.Cases("WORD", "word", 16)
@@ -2569,6 +2574,8 @@ bool X86AsmParser::ParseIntelMemoryOperandSize(unsigned &Size) {
.Cases("ZMMWORD", "zmmword", 512)
.Default(0);
if (Size) {
+ if (SizeStr)
+ *SizeStr = getTok().getString();
const AsmToken &Tok = Lex(); // Eat operand size (e.g., byte, word).
if (!(Tok.getString() == "PTR" || Tok.getString() == "ptr"))
return Error(Tok.getLoc(), "Expected 'PTR' or 'ptr' token!");
@@ -2577,6 +2584,31 @@ bool X86AsmParser::ParseIntelMemoryOperandSize(unsigned &Size) {
return false;
}
+uint16_t RegSizeInBits(MCRegister RegNo, const MCRegisterInfo &MRI) {
+ uint16_t Size = 0;
+ if (X86MCRegisterClasses[X86::GR8RegClassID].contains(RegNo))
+ Size = 8;
+ else if (X86MCRegisterClasses[X86::GR16RegClassID].contains(RegNo))
+ Size = 16;
+ else if (X86MCRegisterClasses[X86::GR32RegClassID].contains(RegNo))
+ Size = 32;
+ else if (X86MCRegisterClasses[X86::GR64RegClassID].contains(RegNo))
+ Size = 64;
+ else if (X86MCRegisterClasses[X86::RFP80RegClassID].contains(RegNo))
+ Size = 80;
+ else if (X86MCRegisterClasses[X86::VR128RegClassID].contains(RegNo))
+ Size = 128;
+ else if (X86MCRegisterClasses[X86::VR128XRegClassID].contains(RegNo))
+ Size = 128;
+ else if (X86MCRegisterClasses[X86::VR256XRegClassID].contains(RegNo))
+ Size = 256;
+ else if (X86MCRegisterClasses[X86::VR512RegClassID].contains(RegNo))
+ Size = 512;
+ else
+ llvm_unreachable("Register without known register class");
+ return Size;
+}
+
bool X86AsmParser::parseIntelOperand(OperandVector &Operands, StringRef Name) {
MCAsmParser &Parser = getParser();
const AsmToken &Tok = Parser.getTok();
@@ -2584,7 +2616,8 @@ bool X86AsmParser::parseIntelOperand(OperandVector &Operands, StringRef Name) {
// Parse optional Size directive.
unsigned Size;
- if (ParseIntelMemoryOperandSize(Size))
+ StringRef SizeStr;
+ if (ParseIntelMemoryOperandSize(Size, &SizeStr))
return true;
bool PtrInOperand = bool(Size);
@@ -2601,9 +2634,20 @@ bool X86AsmParser::parseIntelOperand(OperandVector &Operands, StringRef Name) {
return Error(Start, "rip can only be used as a base register");
// A Register followed by ':' is considered a segment override
if (Tok.isNot(AsmToken::Colon)) {
- if (PtrInOperand)
- return Error(Start, "expected memory operand after 'ptr', "
- "found register operand instead");
+ if (PtrInOperand) {
+ if (!Parser.isParsingMasm())
+ return Error(Start, "expected memory operand after 'ptr', "
+ "found register operand instead");
+
+ // If we are parsing MASM, we are allowed to cast registers to their own
+ // sizes, but not to other types.
+ if (RegSizeInBits(RegNo, *getContext().getRegisterInfo()) != Size)
+ return Error(
+ Start,
+ "cannot cast register '" +
+ StringRef(getContext().getRegisterInfo()->getName(RegNo)) +
+ "' to '" + SizeStr + "'; size does not match");
+ }
Operands.push_back(X86Operand::CreateReg(RegNo, Start, End));
return false;
}
diff --git a/llvm/test/tools/llvm-ml/cast.asm b/llvm/test/tools/llvm-ml/cast.asm
new file mode 100644
index 0000000000000..2b4aaae88866e
--- /dev/null
+++ b/llvm/test/tools/llvm-ml/cast.asm
@@ -0,0 +1,25 @@
+; RUN: llvm-ml -m64 -filetype=s %s /Fo - | FileCheck %s
+
+.code
+
+mov byte ptr al, al
+mov al, byte ptr al
+; CHECK: mov al, al
+; CHECK-NEXT: mov al, al
+
+mov word ptr ax, ax
+mov ax, word ptr ax
+; CHECK: mov ax, ax
+; CHECK-NEXT: mov ax, ax
+
+mov dword ptr eax, eax
+mov eax, dword ptr eax
+; CHECK: mov eax, eax
+; CHECK-NEXT: mov eax, eax
+
+mov qword ptr rax, rax
+mov rax, qword ptr rax
+; CHECK: mov rax, rax
+; CHECK-NEXT: mov rax, rax
+
+END
diff --git a/llvm/test/tools/llvm-ml/cast_errors.asm b/llvm/test/tools/llvm-ml/cast_errors.asm
new file mode 100644
index 0000000000000..60cd9a4454ed8
--- /dev/null
+++ b/llvm/test/tools/llvm-ml/cast_errors.asm
@@ -0,0 +1,41 @@
+; RUN: not llvm-ml -m64 -filetype=s %s /Fo /dev/null 2>&1 | FileCheck %s
+
+.code
+
+mov word ptr al, ax
+; CHECK: error: cannot cast register 'AL' to 'word'; size does not match
+
+mov dword ptr al, eax
+; CHECK: error: cannot cast register 'AL' to 'dword'; size does not match
+
+mov qword ptr al, rax
+; CHECK: error: cannot cast register 'AL' to 'qword'; size does not match
+
+mov byte ptr ax, al
+; CHECK: error: cannot cast register 'AX' to 'byte'; size does not match
+
+mov dword ptr ax, eax
+; CHECK: error: cannot cast register 'AX' to 'dword'; size does not match
+
+mov qword ptr ax, rax
+; CHECK: error: cannot cast register 'AX' to 'qword'; size does not match
+
+mov byte ptr eax, al
+; CHECK: error: cannot cast register 'EAX' to 'byte'; size does not match
+
+mov word ptr eax, ax
+; CHECK: error: cannot cast register 'EAX' to 'word'; size does not match
+
+mov qword ptr eax, rax
+; CHECK: error: cannot cast register 'EAX' to 'qword'; size does not match
+
+mov byte ptr rax, al
+; CHECK: error: cannot cast register 'RAX' to 'byte'; size does not match
+
+mov word ptr rax, ax
+; CHECK: error: cannot cast register 'RAX' to 'word'; size does not match
+
+mov dword ptr rax, eax
+; CHECK: error: cannot cast register 'RAX' to 'dword'; size does not match
+
+END
>From 5fbf8b6af4dbb6ee4171a31ef0e55460fcd98e09 Mon Sep 17 00:00:00 2001
From: Eric Astor <epastor at google.com>
Date: Mon, 24 Mar 2025 15:00:18 +0000
Subject: [PATCH 02/11] Fix includes
---
llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp b/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp
index 475b0016ace68..46483b48e37d2 100644
--- a/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp
+++ b/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp
@@ -14,13 +14,12 @@
#include "MCTargetDesc/X86TargetStreamer.h"
#include "TargetInfo/X86TargetInfo.h"
#include "X86Operand.h"
-#include "third_party/llvm/llvm-project/llvm/include/llvm/ADT/StringRef.h"
-#include "third_party/llvm/llvm-project/llvm/include/llvm/MC/MCRegister.h"
-#include "third_party/llvm/llvm-project/llvm/lib/Target/X86/X86RegisterInfo.h"
+#include "X86RegisterInfo.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringSwitch.h"
+#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/Twine.h"
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCExpr.h"
@@ -31,6 +30,7 @@
#include "llvm/MC/MCParser/MCParsedAsmOperand.h"
#include "llvm/MC/MCParser/MCTargetAsmParser.h"
#include "llvm/MC/MCRegisterInfo.h"
+#include "llvm/MC/MCRegister.h"
#include "llvm/MC/MCSection.h"
#include "llvm/MC/MCStreamer.h"
#include "llvm/MC/MCSubtargetInfo.h"
>From 2bbaea76071fc32e2c00eab97c31ac2d55dadaa7 Mon Sep 17 00:00:00 2001
From: Eric Astor <epastor at google.com>
Date: Mon, 24 Mar 2025 16:50:31 +0000
Subject: [PATCH 03/11] Fix include order
---
llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp b/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp
index 46483b48e37d2..bedff30bc6483 100644
--- a/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp
+++ b/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp
@@ -18,8 +18,8 @@
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/SmallVector.h"
-#include "llvm/ADT/StringSwitch.h"
#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/StringSwitch.h"
#include "llvm/ADT/Twine.h"
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCExpr.h"
@@ -29,8 +29,8 @@
#include "llvm/MC/MCParser/MCAsmParser.h"
#include "llvm/MC/MCParser/MCParsedAsmOperand.h"
#include "llvm/MC/MCParser/MCTargetAsmParser.h"
-#include "llvm/MC/MCRegisterInfo.h"
#include "llvm/MC/MCRegister.h"
+#include "llvm/MC/MCRegisterInfo.h"
#include "llvm/MC/MCSection.h"
#include "llvm/MC/MCStreamer.h"
#include "llvm/MC/MCSubtargetInfo.h"
>From edef7c18614b68434f02912fbbe3e783a42de65a Mon Sep 17 00:00:00 2001
From: Eric Astor <epastor at google.com>
Date: Mon, 24 Mar 2025 21:31:21 +0000
Subject: [PATCH 04/11] Address feedback
---
.../lib/Target/X86/AsmParser/X86AsmParser.cpp | 43 +++++++++----------
1 file changed, 21 insertions(+), 22 deletions(-)
diff --git a/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp b/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp
index bedff30bc6483..2ab859d9cc9b4 100644
--- a/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp
+++ b/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp
@@ -2584,29 +2584,28 @@ bool X86AsmParser::ParseIntelMemoryOperandSize(unsigned &Size,
return false;
}
-uint16_t RegSizeInBits(MCRegister RegNo, const MCRegisterInfo &MRI) {
+uint16_t RegSizeInBits(const MCRegisterInfo &MRI, MCRegister RegNo) {
uint16_t Size = 0;
if (X86MCRegisterClasses[X86::GR8RegClassID].contains(RegNo))
- Size = 8;
- else if (X86MCRegisterClasses[X86::GR16RegClassID].contains(RegNo))
- Size = 16;
- else if (X86MCRegisterClasses[X86::GR32RegClassID].contains(RegNo))
- Size = 32;
- else if (X86MCRegisterClasses[X86::GR64RegClassID].contains(RegNo))
- Size = 64;
- else if (X86MCRegisterClasses[X86::RFP80RegClassID].contains(RegNo))
- Size = 80;
- else if (X86MCRegisterClasses[X86::VR128RegClassID].contains(RegNo))
- Size = 128;
- else if (X86MCRegisterClasses[X86::VR128XRegClassID].contains(RegNo))
- Size = 128;
- else if (X86MCRegisterClasses[X86::VR256XRegClassID].contains(RegNo))
- Size = 256;
- else if (X86MCRegisterClasses[X86::VR512RegClassID].contains(RegNo))
- Size = 512;
- else
- llvm_unreachable("Register without known register class");
- return Size;
+ return 8;
+ if (X86MCRegisterClasses[X86::GR16RegClassID].contains(RegNo))
+ return 16;
+ if (X86MCRegisterClasses[X86::GR32RegClassID].contains(RegNo))
+ return 32;
+ if (X86MCRegisterClasses[X86::GR64RegClassID].contains(RegNo))
+ return 64;
+ if (X86MCRegisterClasses[X86::RFP80RegClassID].contains(RegNo))
+ return 80;
+ if (X86MCRegisterClasses[X86::VR128RegClassID].contains(RegNo))
+ return 128;
+ if (X86MCRegisterClasses[X86::VR128XRegClassID].contains(RegNo))
+ return 128;
+ if (X86MCRegisterClasses[X86::VR256XRegClassID].contains(RegNo))
+ return 256;
+ if (X86MCRegisterClasses[X86::VR512RegClassID].contains(RegNo))
+ return 512;
+ llvm_unreachable("Register without known register class");
+ return 0;
}
bool X86AsmParser::parseIntelOperand(OperandVector &Operands, StringRef Name) {
@@ -2641,7 +2640,7 @@ bool X86AsmParser::parseIntelOperand(OperandVector &Operands, StringRef Name) {
// If we are parsing MASM, we are allowed to cast registers to their own
// sizes, but not to other types.
- if (RegSizeInBits(RegNo, *getContext().getRegisterInfo()) != Size)
+ if (RegSizeInBits(*getContext().getRegisterInfo(), RegNo) != Size)
return Error(
Start,
"cannot cast register '" +
>From ec457bdbcf3b8767219c7ea738e419c885a58284 Mon Sep 17 00:00:00 2001
From: Eric Astor <epastor at google.com>
Date: Mon, 24 Mar 2025 21:33:45 +0000
Subject: [PATCH 05/11] Remove unused variable
---
llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp | 1 -
1 file changed, 1 deletion(-)
diff --git a/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp b/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp
index 2ab859d9cc9b4..441b86342e495 100644
--- a/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp
+++ b/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp
@@ -2585,7 +2585,6 @@ bool X86AsmParser::ParseIntelMemoryOperandSize(unsigned &Size,
}
uint16_t RegSizeInBits(const MCRegisterInfo &MRI, MCRegister RegNo) {
- uint16_t Size = 0;
if (X86MCRegisterClasses[X86::GR8RegClassID].contains(RegNo))
return 8;
if (X86MCRegisterClasses[X86::GR16RegClassID].contains(RegNo))
>From d9d0517ef8ae9e86473d94d797952b47c00f8723 Mon Sep 17 00:00:00 2001
From: Eric Astor <epastor at google.com>
Date: Mon, 24 Mar 2025 21:35:14 +0000
Subject: [PATCH 06/11] Remove trailing return (after llvm_unreachable)
---
llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp | 1 -
1 file changed, 1 deletion(-)
diff --git a/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp b/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp
index 441b86342e495..5515b49c5aac1 100644
--- a/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp
+++ b/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp
@@ -2604,7 +2604,6 @@ uint16_t RegSizeInBits(const MCRegisterInfo &MRI, MCRegister RegNo) {
if (X86MCRegisterClasses[X86::VR512RegClassID].contains(RegNo))
return 512;
llvm_unreachable("Register without known register class");
- return 0;
}
bool X86AsmParser::parseIntelOperand(OperandVector &Operands, StringRef Name) {
>From e253de45c5e3410d823cf6cc92714561d7ee57ac Mon Sep 17 00:00:00 2001
From: Eric Astor <epastor at google.com>
Date: Mon, 24 Mar 2025 22:19:35 +0000
Subject: [PATCH 07/11] Merge related register-class lines
---
llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp b/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp
index 5515b49c5aac1..96f66f29ef2d3 100644
--- a/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp
+++ b/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp
@@ -2595,9 +2595,8 @@ uint16_t RegSizeInBits(const MCRegisterInfo &MRI, MCRegister RegNo) {
return 64;
if (X86MCRegisterClasses[X86::RFP80RegClassID].contains(RegNo))
return 80;
- if (X86MCRegisterClasses[X86::VR128RegClassID].contains(RegNo))
- return 128;
- if (X86MCRegisterClasses[X86::VR128XRegClassID].contains(RegNo))
+ if (X86MCRegisterClasses[X86::VR128RegClassID].contains(RegNo) ||
+ X86MCRegisterClasses[X86::VR128XRegClassID].contains(RegNo))
return 128;
if (X86MCRegisterClasses[X86::VR256XRegClassID].contains(RegNo))
return 256;
>From 07c67a3c1f4277471d4f6ad2dad3b2916083c0f8 Mon Sep 17 00:00:00 2001
From: Eric Astor <epastor at google.com>
Date: Mon, 24 Mar 2025 22:33:47 +0000
Subject: [PATCH 08/11] Improve error messages on mismatched PTR casts
---
llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp | 9 ++++++---
1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp b/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp
index 96f66f29ef2d3..92b159284f5a3 100644
--- a/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp
+++ b/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp
@@ -2637,12 +2637,15 @@ bool X86AsmParser::parseIntelOperand(OperandVector &Operands, StringRef Name) {
// If we are parsing MASM, we are allowed to cast registers to their own
// sizes, but not to other types.
- if (RegSizeInBits(*getContext().getRegisterInfo(), RegNo) != Size)
+ uint16_t RegSize =
+ RegSizeInBits(*getContext().getRegisterInfo(), RegNo);
+ if (RegSize != Size)
return Error(
Start,
- "cannot cast register '" +
+ std::to_string(RegSize) + "-bit register '" +
StringRef(getContext().getRegisterInfo()->getName(RegNo)) +
- "' to '" + SizeStr + "'; size does not match");
+ "' cannot be used as a " + std::to_string(Size) + "-bit " +
+ SizeStr.upper());
}
Operands.push_back(X86Operand::CreateReg(RegNo, Start, End));
return false;
>From ab863ce058ad9eec7eb13774d9b0a3a8e0aacaff Mon Sep 17 00:00:00 2001
From: Eric Astor <epastor at google.com>
Date: Mon, 24 Mar 2025 22:38:18 +0000
Subject: [PATCH 09/11] Update the errors test file
---
llvm/test/tools/llvm-ml/cast_errors.asm | 24 ++++++++++++------------
1 file changed, 12 insertions(+), 12 deletions(-)
diff --git a/llvm/test/tools/llvm-ml/cast_errors.asm b/llvm/test/tools/llvm-ml/cast_errors.asm
index 60cd9a4454ed8..7e3c23da53e52 100644
--- a/llvm/test/tools/llvm-ml/cast_errors.asm
+++ b/llvm/test/tools/llvm-ml/cast_errors.asm
@@ -3,39 +3,39 @@
.code
mov word ptr al, ax
-; CHECK: error: cannot cast register 'AL' to 'word'; size does not match
+; CHECK: error: 8-bit register 'AL' cannot be used as a 16-bit WORD
mov dword ptr al, eax
-; CHECK: error: cannot cast register 'AL' to 'dword'; size does not match
+; CHECK: error: 8-bit register 'AL' cannot be used as a 32-bit DWORD
mov qword ptr al, rax
-; CHECK: error: cannot cast register 'AL' to 'qword'; size does not match
+; CHECK: error: 8-bit register 'AL' cannot be used as a 64-bit QWORD
mov byte ptr ax, al
-; CHECK: error: cannot cast register 'AX' to 'byte'; size does not match
+; CHECK: error: 16-bit register 'AX' cannot be used as a 8-bit BYTE
mov dword ptr ax, eax
-; CHECK: error: cannot cast register 'AX' to 'dword'; size does not match
+; CHECK: error: 16-bit register 'AX' cannot be used as a 32-bit DWORD
mov qword ptr ax, rax
-; CHECK: error: cannot cast register 'AX' to 'qword'; size does not match
+; CHECK: error: 16-bit register 'AX' cannot be used as a 64-bit QWORD
mov byte ptr eax, al
-; CHECK: error: cannot cast register 'EAX' to 'byte'; size does not match
+; CHECK: error: 32-bit register 'EAX' cannot be used as a 8-bit BYTE
mov word ptr eax, ax
-; CHECK: error: cannot cast register 'EAX' to 'word'; size does not match
+; CHECK: error: 32-bit register 'EAX' cannot be used as a 16-bit WORD
mov qword ptr eax, rax
-; CHECK: error: cannot cast register 'EAX' to 'qword'; size does not match
+; CHECK: error: 32-bit register 'EAX' cannot be used as a 64-bit QWORD
mov byte ptr rax, al
-; CHECK: error: cannot cast register 'RAX' to 'byte'; size does not match
+; CHECK: error: 64-bit register 'RAX' cannot be used as a 8-bit BYTE
mov word ptr rax, ax
-; CHECK: error: cannot cast register 'RAX' to 'word'; size does not match
+; CHECK: error: 64-bit register 'RAX' cannot be used as a 16-bit WORD
mov dword ptr rax, eax
-; CHECK: error: cannot cast register 'RAX' to 'dword'; size does not match
+; CHECK: error: 64-bit register 'RAX' cannot be used as a 32-bit DWORD
END
>From 23ac3811854ef899469df06f767d41fc1445cc42 Mon Sep 17 00:00:00 2001
From: Eric Astor <epastor at google.com>
Date: Fri, 25 Apr 2025 18:38:30 -0400
Subject: [PATCH 10/11] Remove cast support for vector registers, and improve
error tests
---
.../lib/Target/X86/AsmParser/X86AsmParser.cpp | 16 ++++++-------
llvm/test/tools/llvm-ml/cast_errors.asm | 24 +++++++++----------
2 files changed, 20 insertions(+), 20 deletions(-)
diff --git a/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp b/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp
index 92b159284f5a3..0a51848401f70 100644
--- a/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp
+++ b/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp
@@ -2595,14 +2595,8 @@ uint16_t RegSizeInBits(const MCRegisterInfo &MRI, MCRegister RegNo) {
return 64;
if (X86MCRegisterClasses[X86::RFP80RegClassID].contains(RegNo))
return 80;
- if (X86MCRegisterClasses[X86::VR128RegClassID].contains(RegNo) ||
- X86MCRegisterClasses[X86::VR128XRegClassID].contains(RegNo))
- return 128;
- if (X86MCRegisterClasses[X86::VR256XRegClassID].contains(RegNo))
- return 256;
- if (X86MCRegisterClasses[X86::VR512RegClassID].contains(RegNo))
- return 512;
- llvm_unreachable("Register without known register class");
+ // Unknown register size
+ return 0;
}
bool X86AsmParser::parseIntelOperand(OperandVector &Operands, StringRef Name) {
@@ -2639,6 +2633,12 @@ bool X86AsmParser::parseIntelOperand(OperandVector &Operands, StringRef Name) {
// sizes, but not to other types.
uint16_t RegSize =
RegSizeInBits(*getContext().getRegisterInfo(), RegNo);
+ if (RegSize == 0)
+ return Error(
+ Start,
+ "cannot cast register '" +
+ StringRef(getContext().getRegisterInfo()->getName(RegNo)) +
+ "'; its size is not easily defined.");
if (RegSize != Size)
return Error(
Start,
diff --git a/llvm/test/tools/llvm-ml/cast_errors.asm b/llvm/test/tools/llvm-ml/cast_errors.asm
index 7e3c23da53e52..ca51648236573 100644
--- a/llvm/test/tools/llvm-ml/cast_errors.asm
+++ b/llvm/test/tools/llvm-ml/cast_errors.asm
@@ -3,39 +3,39 @@
.code
mov word ptr al, ax
-; CHECK: error: 8-bit register 'AL' cannot be used as a 16-bit WORD
+; CHECK: [[#@LINE-1]]:14: error: 8-bit register 'AL' cannot be used as a 16-bit WORD
mov dword ptr al, eax
-; CHECK: error: 8-bit register 'AL' cannot be used as a 32-bit DWORD
+; CHECK: [[#@LINE-1]]:15: error: 8-bit register 'AL' cannot be used as a 32-bit DWORD
mov qword ptr al, rax
-; CHECK: error: 8-bit register 'AL' cannot be used as a 64-bit QWORD
+; CHECK: [[#@LINE-1]]:15: error: 8-bit register 'AL' cannot be used as a 64-bit QWORD
mov byte ptr ax, al
-; CHECK: error: 16-bit register 'AX' cannot be used as a 8-bit BYTE
+; CHECK: [[#@LINE-1]]:14: error: 16-bit register 'AX' cannot be used as a 8-bit BYTE
mov dword ptr ax, eax
-; CHECK: error: 16-bit register 'AX' cannot be used as a 32-bit DWORD
+; CHECK: [[#@LINE-1]]:15: error: 16-bit register 'AX' cannot be used as a 32-bit DWORD
mov qword ptr ax, rax
-; CHECK: error: 16-bit register 'AX' cannot be used as a 64-bit QWORD
+; CHECK: [[#@LINE-1]]:15: error: 16-bit register 'AX' cannot be used as a 64-bit QWORD
mov byte ptr eax, al
-; CHECK: error: 32-bit register 'EAX' cannot be used as a 8-bit BYTE
+; CHECK: [[#@LINE-1]]:14: error: 32-bit register 'EAX' cannot be used as a 8-bit BYTE
mov word ptr eax, ax
-; CHECK: error: 32-bit register 'EAX' cannot be used as a 16-bit WORD
+; CHECK: [[#@LINE-1]]:14: error: 32-bit register 'EAX' cannot be used as a 16-bit WORD
mov qword ptr eax, rax
-; CHECK: error: 32-bit register 'EAX' cannot be used as a 64-bit QWORD
+; CHECK: [[#@LINE-1]]:15: error: 32-bit register 'EAX' cannot be used as a 64-bit QWORD
mov byte ptr rax, al
-; CHECK: error: 64-bit register 'RAX' cannot be used as a 8-bit BYTE
+; CHECK: [[#@LINE-1]]:14: error: 64-bit register 'RAX' cannot be used as a 8-bit BYTE
mov word ptr rax, ax
-; CHECK: error: 64-bit register 'RAX' cannot be used as a 16-bit WORD
+; CHECK: [[#@LINE-1]]:14: error: 64-bit register 'RAX' cannot be used as a 16-bit WORD
mov dword ptr rax, eax
-; CHECK: error: 64-bit register 'RAX' cannot be used as a 32-bit DWORD
+; CHECK: [[#@LINE-1]]:15: error: 64-bit register 'RAX' cannot be used as a 32-bit DWORD
END
>From e6002d21efc8f2e138e6aaf63192dcbffb4098f5 Mon Sep 17 00:00:00 2001
From: Eric Astor <epastor at google.com>
Date: Fri, 2 May 2025 10:58:24 -0400
Subject: [PATCH 11/11] Remove cast support for extended-float registers as
well
---
llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp | 2 --
1 file changed, 2 deletions(-)
diff --git a/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp b/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp
index 0a51848401f70..a39c0a576bf5c 100644
--- a/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp
+++ b/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp
@@ -2593,8 +2593,6 @@ uint16_t RegSizeInBits(const MCRegisterInfo &MRI, MCRegister RegNo) {
return 32;
if (X86MCRegisterClasses[X86::GR64RegClassID].contains(RegNo))
return 64;
- if (X86MCRegisterClasses[X86::RFP80RegClassID].contains(RegNo))
- return 80;
// Unknown register size
return 0;
}
More information about the llvm-commits
mailing list