diff --git a/llvm/docs/LangRef.rst b/llvm/docs/LangRef.rst --- a/llvm/docs/LangRef.rst +++ b/llvm/docs/LangRef.rst @@ -4994,7 +4994,8 @@ - ``w``: A 32, 64, or 128-bit floating-point, SIMD or SVE vector register. - ``x``: Like w, but restricted to registers 0 to 15 inclusive. - ``y``: Like w, but restricted to SVE vector registers Z0 to Z7 inclusive. -- ``Upl``: One of the low eight SVE predicate registers (P0 to P7) +- ``Uph``: One of the upper eight SVE predicate registers (P8 to P15) +- ``Upl``: One of the lower eight SVE predicate registers (P0 to P7) - ``Upa``: Any of the SVE predicate registers (P0 to P15) AMDGPU: diff --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp --- a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp +++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp @@ -9978,19 +9978,33 @@ return "r"; } -enum PredicateConstraint { - Upl, - Upa, - Invalid -}; +enum PredicateConstraint { Uph, Upl, Upa, Invalid }; static PredicateConstraint parsePredicateConstraint(StringRef Constraint) { - PredicateConstraint P = PredicateConstraint::Invalid; - if (Constraint == "Upa") - P = PredicateConstraint::Upa; - if (Constraint == "Upl") - P = PredicateConstraint::Upl; - return P; + if (Constraint == "Uph") + return PredicateConstraint::Uph; + else if (Constraint == "Upl") + return PredicateConstraint::Upl; + else if (Constraint == "Upa") + return PredicateConstraint::Upa; + return PredicateConstraint::Invalid; +} + +static const TargetRegisterClass * +getPredicateRegisterClass(PredicateConstraint Constraint, EVT VT) { + if (!VT.isScalableVector() || VT.getVectorElementType() != MVT::i1) + return nullptr; + + switch (Constraint) { + default: + return nullptr; + case PredicateConstraint::Uph: + return &AArch64::PPR_p8to15RegClass; + case PredicateConstraint::Upl: + return &AArch64::PPR_3bRegClass; + case PredicateConstraint::Upa: + return &AArch64::PPRRegClass; + } } // The set of cc code supported is from @@ -10182,13 +10196,8 @@ } } else { PredicateConstraint PC = parsePredicateConstraint(Constraint); - if (PC != PredicateConstraint::Invalid) { - if (!VT.isScalableVector() || VT.getVectorElementType() != MVT::i1) - return std::make_pair(0U, nullptr); - bool restricted = (PC == PredicateConstraint::Upl); - return restricted ? std::make_pair(0U, &AArch64::PPR_3bRegClass) - : std::make_pair(0U, &AArch64::PPRRegClass); - } + if (const TargetRegisterClass *RegClass = getPredicateRegisterClass(PC, VT)) + return std::make_pair(0U, RegClass); } if (StringRef("{cc}").equals_insensitive(Constraint) || parseConstraintCode(Constraint) != AArch64CC::Invalid) diff --git a/llvm/test/CodeGen/AArch64/aarch64-sve-asm.ll b/llvm/test/CodeGen/AArch64/aarch64-sve-asm.ll --- a/llvm/test/CodeGen/AArch64/aarch64-sve-asm.ll +++ b/llvm/test/CodeGen/AArch64/aarch64-sve-asm.ll @@ -68,3 +68,14 @@ %1 = tail call asm "incp $0.s, $1", "=w,@3Upa,0"( %Pg, %Zn) ret %1 } + +; Function Attrs: nounwind readnone +; CHECK: [[ARG1:%[0-9]+]]:zpr = COPY $z1 +; CHECK: [[ARG2:%[0-9]+]]:zpr = COPY $z0 +; CHECK: [[ARG3:%[0-9]+]]:ppr = COPY $p0 +; CHECK: [[ARG4:%[0-9]+]]:ppr_p8to15 = COPY [[ARG3]] +; CHECK: INLINEASM {{.*}} [[ARG4]] +define @test_svfadd_f16_Uph_constraint( %Pg, %Zn, %Zm) { + %1 = tail call asm "fadd $0.h, $1/m, $2.h, $3.h", "=w,@3Uph,w,w"( %Pg, %Zn, %Zm) + ret %1 +}