Index: llvm/trunk/lib/Target/AArch64/AArch64ISelLowering.cpp =================================================================== --- llvm/trunk/lib/Target/AArch64/AArch64ISelLowering.cpp +++ llvm/trunk/lib/Target/AArch64/AArch64ISelLowering.cpp @@ -5443,6 +5443,8 @@ return std::make_pair(0U, &AArch64::GPR64commonRegClass); return std::make_pair(0U, &AArch64::GPR32commonRegClass); case 'w': + if (!Subtarget->hasFPARMv8()) + break; if (VT.getSizeInBits() == 16) return std::make_pair(0U, &AArch64::FPR16RegClass); if (VT.getSizeInBits() == 32) @@ -5455,6 +5457,8 @@ // The instructions that this constraint is designed for can // only take 128-bit registers so just use that regclass. case 'x': + if (!Subtarget->hasFPARMv8()) + break; if (VT.getSizeInBits() == 128) return std::make_pair(0U, &AArch64::FPR128_loRegClass); break; @@ -5490,6 +5494,11 @@ } } + if (Res.second && !Subtarget->hasFPARMv8() && + !AArch64::GPR32allRegClass.hasSubClassEq(Res.second) && + !AArch64::GPR64allRegClass.hasSubClassEq(Res.second)) + return std::make_pair(0U, nullptr); + return Res; } Index: llvm/trunk/test/CodeGen/AArch64/inlineasm-illegal-type.ll =================================================================== --- llvm/trunk/test/CodeGen/AArch64/inlineasm-illegal-type.ll +++ llvm/trunk/test/CodeGen/AArch64/inlineasm-illegal-type.ll @@ -0,0 +1,17 @@ +;RUN: not llc -mtriple=aarch64-linux-gnu -mattr=-fp-armv8 < %s 2>&1 | FileCheck %s + +; CHECK: error: couldn't allocate output register for constraint '{d0}' +; CHECK: error: couldn't allocate output register for constraint 'w' + +define hidden double @test1(double %xx) local_unnamed_addr #0 { +entry: + %0 = tail call double asm "frintp ${0:d}, ${0:d}", "={d0}"() + ret double %0 +} + +define hidden double @test2(double %xx) local_unnamed_addr #0 { +entry: + %0 = tail call double asm "frintp ${0:d}, ${0:d}", "=w"() + ret double %0 +} +