Index: llvm/trunk/docs/LangRef.rst =================================================================== --- llvm/trunk/docs/LangRef.rst +++ llvm/trunk/docs/LangRef.rst @@ -3654,8 +3654,8 @@ ``d0-d31``, or ``q0-q15``. - ``x``: A 32, 64, or 128-bit floating-point/SIMD register: ``s0-s15``, ``d0-d7``, or ``q0-q3``. -- ``t``: A floating-point/SIMD register, only supports 32-bit values: - ``s0-s31``. +- ``t``: A low floating-point/SIMD register: ``s0-s31``, ``d0-d16``, or + ``q0-q8``. ARM's Thumb1 mode: @@ -3674,8 +3674,8 @@ ``d0-d31``, or ``q0-q15``. - ``x``: A 32, 64, or 128-bit floating-point/SIMD register: ``s0-s15``, ``d0-d7``, or ``q0-q3``. -- ``t``: A floating-point/SIMD register, only supports 32-bit values: - ``s0-s31``. +- ``t``: A low floating-point/SIMD register: ``s0-s31``, ``d0-d16``, or + ``q0-q8``. Hexagon: Index: llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp =================================================================== --- llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp +++ llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp @@ -13467,8 +13467,14 @@ return RCPair(0U, &ARM::QPR_8RegClass); break; case 't': + if (VT == MVT::Other) + break; if (VT == MVT::f32 || VT == MVT::i32) return RCPair(0U, &ARM::SPRRegClass); + if (VT.getSizeInBits() == 64) + return RCPair(0U, &ARM::DPR_VFP2RegClass); + if (VT.getSizeInBits() == 128) + return RCPair(0U, &ARM::QPR_VFP2RegClass); break; } } Index: llvm/trunk/test/CodeGen/ARM/inlineasm-error-t-toofewregs.ll =================================================================== --- llvm/trunk/test/CodeGen/ARM/inlineasm-error-t-toofewregs.ll +++ llvm/trunk/test/CodeGen/ARM/inlineasm-error-t-toofewregs.ll @@ -0,0 +1,9 @@ +; RUN: not llc -mtriple=armv8-eabi -mattr=+neon %s -o /dev/null 2<&1 | FileCheck %s + +; CHECK: inline assembly requires more registers than available +define <4 x float> @t-constraint-float-vectors-too-few-regs(<4 x float> %a, <4 x float> %b) { +entry: + %0 = tail call { <4 x float>, <4 x float>, <4 x float>, <4 x float>, <4 x float>, <4 x float>, <4 x float>, <4 x float>, <4 x float>, <4 x float> } asm "vadd.F32 $0, $9, $10\0A\09vadd.F32 $1, $9, $10\0A\09vadd.F32 $2, $9, $10\0A\09vadd.F32 $3, $9, $10\0A\09vadd.F32 $4, $9, $10\0A\09vadd.F32 $5, $9, $10\0A\09vadd.F32 $6, $9, $10\0A\09vadd.F32 $7, $9, $10\0A\09vadd.F32 $8, $9, $10", "=t,=t,=t,=t,=t,=t,=t,=t,=t,=t,t,t"(<4 x float> %a, <4 x float> %b) + %asmresult = extractvalue { <4 x float>, <4 x float>, <4 x float>, <4 x float>, <4 x float>, <4 x float>, <4 x float>, <4 x float>, <4 x float>, <4 x float> } %0, 0 + ret <4 x float> %asmresult +} Index: llvm/trunk/test/CodeGen/ARM/inlineasm.ll =================================================================== --- llvm/trunk/test/CodeGen/ARM/inlineasm.ll +++ llvm/trunk/test/CodeGen/ARM/inlineasm.ll @@ -16,3 +16,35 @@ %ret = call float asm "vcvt.f32.s32 $0, $1\0A", "=t,t"(i32 %i) ret float %ret } + +define <2 x i32> @t-constraint-int-vector-64bit(<2 x float> %x) { +entry: + ; CHECK-LABEL: t-constraint-int-vector-64bit + ; CHECK: vcvt.s32.f32 {{d[0-9]+}}, {{d[0-9]+}} + %0 = tail call <2 x i32> asm "vcvt.s32.f32 $0, $1", "=t,t"(<2 x float> %x) + ret <2 x i32> %0 +} + +define <4 x i32> @t-constraint-int-vector-128bit(<4 x float> %x) { +entry: + ; CHECK-LABEL: t-constraint-int-vector-128bit + ; CHECK: vcvt.s32.f32 {{q[0-7]}}, {{q[0-7]}} + %0 = tail call <4 x i32> asm "vcvt.s32.f32 $0, $1", "=t,t"(<4 x float> %x) + ret <4 x i32> %0 +} + +define <2 x float> @t-constraint-float-vector-64bit(<2 x float> %a, <2 x float> %b) { +entry: + ; CHECK-LABEL: t-constraint-float-vector-64bit + ; CHECK: vadd.f32 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}} + %0 = tail call <2 x float> asm "vadd.f32 $0, $1, $2", "=t,t,t"(<2 x float> %a, <2 x float> %b) + ret <2 x float> %0 +} + +define <4 x float> @t-constraint-float-vector-128bit(<4 x float> %a, <4 x float> %b) { +entry: + ; CHECK-LABEL: t-constraint-float-vector-128bit + ; CHECK: vadd.f32 q{{[0-7]}}, q{{[0-7]}}, q{{[0-7]}} + %0 = tail call <4 x float> asm "vadd.f32 $0, $1, $2", "=t,t,t"(<4 x float> %a, <4 x float> %b) + ret <4 x float> %0 +}