From 37f92d70fbc4e6d817fef72919a3aa3ce3785e3e Mon Sep 17 00:00:00 2001 From: Oliver Stannard Date: Fri, 7 Feb 2025 11:23:46 +0000 Subject: [PATCH 1/2] [ARM] Reject fixed-point VCVT with different registers These instructions only have one register field in their encoding, so both registers in the assembly must be the same. --- .../lib/Target/ARM/AsmParser/ARMAsmParser.cpp | 31 +++++++++++ llvm/test/MC/ARM/vcvt-fixed-point-errors.s | 51 +++++++++++++++++++ 2 files changed, 82 insertions(+) create mode 100644 llvm/test/MC/ARM/vcvt-fixed-point-errors.s diff --git a/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp b/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp index dad91c6a969e8..325dfb33762a6 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 0000000000000..90e9da054a908 --- /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 + From 7972a3dcea5cfb2b9079c18086dbe619a5dd4b16 Mon Sep 17 00:00:00 2001 From: Oliver Stannard Date: Fri, 7 Feb 2025 13:51:32 +0000 Subject: [PATCH 2/2] Fix llvm-mca tests which were using invalid these instructions --- llvm/test/tools/llvm-mca/ARM/m55-fp.s | 48 +++++++++++++-------------- llvm/test/tools/llvm-mca/ARM/m7-fp.s | 32 +++++++++--------- llvm/test/tools/llvm-mca/ARM/m85-fp.s | 48 +++++++++++++-------------- 3 files changed, 64 insertions(+), 64 deletions(-) diff --git a/llvm/test/tools/llvm-mca/ARM/m55-fp.s b/llvm/test/tools/llvm-mca/ARM/m55-fp.s index 6318cfa9d6e9c..1668f58c7937f 100644 --- a/llvm/test/tools/llvm-mca/ARM/m55-fp.s +++ b/llvm/test/tools/llvm-mca/ARM/m55-fp.s @@ -21,30 +21,30 @@ vcmpe.f32 s1, #0.0 vcmpe.f64 d1, #0.0 vcvt.f32.f64 s1, d2 vcvt.f64.f32 d1, s1 -vcvt.f16.u16 s1, s2, #8 -vcvt.f16.s16 s1, s2, #8 -vcvt.f16.u32 s1, s2, #8 -vcvt.f16.s32 s1, s2, #8 -vcvt.u16.f16 s1, s2, #8 -vcvt.s16.f16 s1, s2, #8 -vcvt.u32.f16 s1, s2, #8 -vcvt.s32.f16 s1, s2, #8 -vcvt.f32.u16 s1, s2, #8 -vcvt.f32.s16 s1, s2, #8 -vcvt.f32.u32 s1, s2, #8 -vcvt.f32.s32 s1, s2, #8 -vcvt.u16.f32 s1, s2, #8 -vcvt.s16.f32 s1, s2, #8 -vcvt.u32.f32 s1, s2, #8 -vcvt.s32.f32 s1, s2, #8 -vcvt.f64.u16 d1, d2, #8 -vcvt.f64.s16 d1, d2, #8 -vcvt.f64.u32 d1, d2, #8 -vcvt.f64.s32 d1, d2, #8 -vcvt.u16.f64 d1, d2, #8 -vcvt.s16.f64 d1, d2, #8 -vcvt.u32.f64 d1, d2, #8 -vcvt.s32.f64 d1, d2, #8 +vcvt.f16.u16 s1, s1, #8 +vcvt.f16.s16 s1, s1, #8 +vcvt.f16.u32 s1, s1, #8 +vcvt.f16.s32 s1, s1, #8 +vcvt.u16.f16 s1, s1, #8 +vcvt.s16.f16 s1, s1, #8 +vcvt.u32.f16 s1, s1, #8 +vcvt.s32.f16 s1, s1, #8 +vcvt.f32.u16 s1, s1, #8 +vcvt.f32.s16 s1, s1, #8 +vcvt.f32.u32 s1, s1, #8 +vcvt.f32.s32 s1, s1, #8 +vcvt.u16.f32 s1, s1, #8 +vcvt.s16.f32 s1, s1, #8 +vcvt.u32.f32 s1, s1, #8 +vcvt.s32.f32 s1, s1, #8 +vcvt.f64.u16 d1, d1, #8 +vcvt.f64.s16 d1, d1, #8 +vcvt.f64.u32 d1, d1, #8 +vcvt.f64.s32 d1, d1, #8 +vcvt.u16.f64 d1, d1, #8 +vcvt.s16.f64 d1, d1, #8 +vcvt.u32.f64 d1, d1, #8 +vcvt.s32.f64 d1, d1, #8 vcvt.u32.f16 s1, s2 vcvt.s32.f16 s1, s2 vcvt.u32.f32 s1, s2 diff --git a/llvm/test/tools/llvm-mca/ARM/m7-fp.s b/llvm/test/tools/llvm-mca/ARM/m7-fp.s index dcf9723461dec..dba7ff92f30cb 100644 --- a/llvm/test/tools/llvm-mca/ARM/m7-fp.s +++ b/llvm/test/tools/llvm-mca/ARM/m7-fp.s @@ -9,22 +9,22 @@ vcmp.f32 s1, s2 vcmp.f64 d1, d2 vcvt.f32.f64 s1, d2 vcvt.f64.f32 d1, s1 -vcvt.f32.u16 s1, s2, #8 -vcvt.f32.s16 s1, s2, #8 -vcvt.f32.u32 s1, s2, #8 -vcvt.f32.s32 s1, s2, #8 -vcvt.u16.f32 s1, s2, #8 -vcvt.s16.f32 s1, s2, #8 -vcvt.u32.f32 s1, s2, #8 -vcvt.s32.f32 s1, s2, #8 -vcvt.f64.u16 d1, d2, #8 -vcvt.f64.s16 d1, d2, #8 -vcvt.f64.u32 d1, d2, #8 -vcvt.f64.s32 d1, d2, #8 -vcvt.u16.f64 d1, d2, #8 -vcvt.s16.f64 d1, d2, #8 -vcvt.u32.f64 d1, d2, #8 -vcvt.s32.f64 d1, d2, #8 +vcvt.f32.u16 s1, s1, #8 +vcvt.f32.s16 s1, s1, #8 +vcvt.f32.u32 s1, s1, #8 +vcvt.f32.s32 s1, s1, #8 +vcvt.u16.f32 s1, s1, #8 +vcvt.s16.f32 s1, s1, #8 +vcvt.u32.f32 s1, s1, #8 +vcvt.s32.f32 s1, s1, #8 +vcvt.f64.u16 d1, d1, #8 +vcvt.f64.s16 d1, d1, #8 +vcvt.f64.u32 d1, d1, #8 +vcvt.f64.s32 d1, d1, #8 +vcvt.u16.f64 d1, d1, #8 +vcvt.s16.f64 d1, d1, #8 +vcvt.u32.f64 d1, d1, #8 +vcvt.s32.f64 d1, d1, #8 vcvt.u32.f32 s1, s2 vcvt.s32.f32 s1, s2 vcvt.u32.f64 s1, d2 diff --git a/llvm/test/tools/llvm-mca/ARM/m85-fp.s b/llvm/test/tools/llvm-mca/ARM/m85-fp.s index edc46060fe0f3..0fc1b394de2dc 100644 --- a/llvm/test/tools/llvm-mca/ARM/m85-fp.s +++ b/llvm/test/tools/llvm-mca/ARM/m85-fp.s @@ -21,30 +21,30 @@ vcmpe.f32 s1, #0.0 vcmpe.f64 d1, #0.0 vcvt.f32.f64 s1, d2 vcvt.f64.f32 d1, s1 -vcvt.f16.u16 s1, s2, #8 -vcvt.f16.s16 s1, s2, #8 -vcvt.f16.u32 s1, s2, #8 -vcvt.f16.s32 s1, s2, #8 -vcvt.u16.f16 s1, s2, #8 -vcvt.s16.f16 s1, s2, #8 -vcvt.u32.f16 s1, s2, #8 -vcvt.s32.f16 s1, s2, #8 -vcvt.f32.u16 s1, s2, #8 -vcvt.f32.s16 s1, s2, #8 -vcvt.f32.u32 s1, s2, #8 -vcvt.f32.s32 s1, s2, #8 -vcvt.u16.f32 s1, s2, #8 -vcvt.s16.f32 s1, s2, #8 -vcvt.u32.f32 s1, s2, #8 -vcvt.s32.f32 s1, s2, #8 -vcvt.f64.u16 d1, d2, #8 -vcvt.f64.s16 d1, d2, #8 -vcvt.f64.u32 d1, d2, #8 -vcvt.f64.s32 d1, d2, #8 -vcvt.u16.f64 d1, d2, #8 -vcvt.s16.f64 d1, d2, #8 -vcvt.u32.f64 d1, d2, #8 -vcvt.s32.f64 d1, d2, #8 +vcvt.f16.u16 s1, s1, #8 +vcvt.f16.s16 s1, s1, #8 +vcvt.f16.u32 s1, s1, #8 +vcvt.f16.s32 s1, s1, #8 +vcvt.u16.f16 s1, s1, #8 +vcvt.s16.f16 s1, s1, #8 +vcvt.u32.f16 s1, s1, #8 +vcvt.s32.f16 s1, s1, #8 +vcvt.f32.u16 s1, s1, #8 +vcvt.f32.s16 s1, s1, #8 +vcvt.f32.u32 s1, s1, #8 +vcvt.f32.s32 s1, s1, #8 +vcvt.u16.f32 s1, s1, #8 +vcvt.s16.f32 s1, s1, #8 +vcvt.u32.f32 s1, s1, #8 +vcvt.s32.f32 s1, s1, #8 +vcvt.f64.u16 d1, d1, #8 +vcvt.f64.s16 d1, d1, #8 +vcvt.f64.u32 d1, d1, #8 +vcvt.f64.s32 d1, d1, #8 +vcvt.u16.f64 d1, d1, #8 +vcvt.s16.f64 d1, d1, #8 +vcvt.u32.f64 d1, d1, #8 +vcvt.s32.f64 d1, d1, #8 vcvt.u32.f16 s1, s2 vcvt.s32.f16 s1, s2 vcvt.u32.f32 s1, s2