From 730dbfa6d546cf5f7d8ab546dda784896296efaf Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Wed, 10 Sep 2025 15:42:41 +0200 Subject: [PATCH] [ARM] Allow s constraints on half Fix a regression from https://github.com/llvm/llvm-project/pull/147559. --- llvm/lib/Target/ARM/ARMISelLowering.cpp | 8 ++- llvm/test/CodeGen/ARM/inlineasm-fp-half.ll | 77 ++++++++++++++++++++++ 2 files changed, 82 insertions(+), 3 deletions(-) diff --git a/llvm/lib/Target/ARM/ARMISelLowering.cpp b/llvm/lib/Target/ARM/ARMISelLowering.cpp index d4d3c70095279..4af2721562d7c 100644 --- a/llvm/lib/Target/ARM/ARMISelLowering.cpp +++ b/llvm/lib/Target/ARM/ARMISelLowering.cpp @@ -20304,9 +20304,11 @@ ARMTargetLowering::getSingleConstraintMatchWeight( static bool isIncompatibleReg(const MCPhysReg &PR, MVT VT) { if (PR == 0 || VT == MVT::Other) return false; - return (ARM::SPRRegClass.contains(PR) && VT != MVT::f32 && VT != MVT::i32) || - (ARM::DPRRegClass.contains(PR) && VT != MVT::f64 && - !VT.is64BitVector()); + if (ARM::SPRRegClass.contains(PR)) + return VT != MVT::f32 && VT != MVT::f16 && VT != MVT::i32; + if (ARM::DPRRegClass.contains(PR)) + return VT != MVT::f64 && !VT.is64BitVector(); + return false; } using RCPair = std::pair; diff --git a/llvm/test/CodeGen/ARM/inlineasm-fp-half.ll b/llvm/test/CodeGen/ARM/inlineasm-fp-half.ll index 554e5ba72c5d4..1a0b2246f23f5 100644 --- a/llvm/test/CodeGen/ARM/inlineasm-fp-half.ll +++ b/llvm/test/CodeGen/ARM/inlineasm-fp-half.ll @@ -495,3 +495,80 @@ entry: %0 = tail call bfloat asm "vmov $0, $1", "=x,x"(bfloat %x) ret bfloat %0 } + +define half @half_s(half %x) nounwind { +; NO-FP16-SOFTFP-LABEL: half_s: +; NO-FP16-SOFTFP: @ %bb.0: @ %entry +; NO-FP16-SOFTFP-NEXT: vmov s2, r0 +; NO-FP16-SOFTFP-NEXT: @APP +; NO-FP16-SOFTFP-NEXT: vmov.f32 s1, s2 +; NO-FP16-SOFTFP-NEXT: @NO_APP +; NO-FP16-SOFTFP-NEXT: vmov r0, s1 +; NO-FP16-SOFTFP-NEXT: bx lr +; +; NO-FP16-HARD-LABEL: half_s: +; NO-FP16-HARD: @ %bb.0: @ %entry +; NO-FP16-HARD-NEXT: vmov.f32 s2, s0 +; NO-FP16-HARD-NEXT: @APP +; NO-FP16-HARD-NEXT: vmov.f32 s1, s2 +; NO-FP16-HARD-NEXT: @NO_APP +; NO-FP16-HARD-NEXT: vmov.f32 s0, s1 +; NO-FP16-HARD-NEXT: bx lr +; +; FP16-SOFTFP-LABEL: half_s: +; FP16-SOFTFP: @ %bb.0: @ %entry +; FP16-SOFTFP-NEXT: vmov.f16 s2, r0 +; FP16-SOFTFP-NEXT: @APP +; FP16-SOFTFP-NEXT: vmov.f32 s1, s2 +; FP16-SOFTFP-NEXT: @NO_APP +; FP16-SOFTFP-NEXT: vmov r0, s1 +; FP16-SOFTFP-NEXT: bx lr +; +; FP16-HARD-LABEL: half_s: +; FP16-HARD: @ %bb.0: @ %entry +; FP16-HARD-NEXT: vmov.f32 s2, s0 +; FP16-HARD-NEXT: @APP +; FP16-HARD-NEXT: vmov.f32 s1, s2 +; FP16-HARD-NEXT: @NO_APP +; FP16-HARD-NEXT: vmov.f32 s0, s1 +; FP16-HARD-NEXT: bx lr +; +; BF16-SOFTFP-LABEL: half_s: +; BF16-SOFTFP: @ %bb.0: @ %entry +; BF16-SOFTFP-NEXT: vmov.f16 s2, r0 +; BF16-SOFTFP-NEXT: @APP +; BF16-SOFTFP-NEXT: vmov.f32 s1, s2 +; BF16-SOFTFP-NEXT: @NO_APP +; BF16-SOFTFP-NEXT: vmov r0, s1 +; BF16-SOFTFP-NEXT: bx lr +; +; SIMD-BF16-SOFTFP-LABEL: half_s: +; SIMD-BF16-SOFTFP: @ %bb.0: @ %entry +; SIMD-BF16-SOFTFP-NEXT: vmov.f16 s2, r0 +; SIMD-BF16-SOFTFP-NEXT: @APP +; SIMD-BF16-SOFTFP-NEXT: vmov.f32 s1, s2 +; SIMD-BF16-SOFTFP-NEXT: @NO_APP +; SIMD-BF16-SOFTFP-NEXT: vmov r0, s1 +; SIMD-BF16-SOFTFP-NEXT: bx lr +; +; BF16-HARD-LABEL: half_s: +; BF16-HARD: @ %bb.0: @ %entry +; BF16-HARD-NEXT: vmov.f32 s2, s0 +; BF16-HARD-NEXT: @APP +; BF16-HARD-NEXT: vmov.f32 s1, s2 +; BF16-HARD-NEXT: @NO_APP +; BF16-HARD-NEXT: vmov.f32 s0, s1 +; BF16-HARD-NEXT: bx lr +; +; SIMD-BF16-HARD-LABEL: half_s: +; SIMD-BF16-HARD: @ %bb.0: @ %entry +; SIMD-BF16-HARD-NEXT: vmov.f32 s2, s0 +; SIMD-BF16-HARD-NEXT: @APP +; SIMD-BF16-HARD-NEXT: vmov.f32 s1, s2 +; SIMD-BF16-HARD-NEXT: @NO_APP +; SIMD-BF16-HARD-NEXT: vmov.f32 s0, s1 +; SIMD-BF16-HARD-NEXT: bx lr +entry: + %0 = tail call half asm "vmov $0, $1", "={s1},{s2}"(half %x) + ret half %0 +}