kmclaughlin updated this revision to Diff 219526. kmclaughlin added a comment.
- Renamed the //isPredicateConstraint// function to //parsePredicateConstraint// - Added more thorough checks to the tests in aarch64-sve-asm.ll CHANGES SINCE LAST ACTION https://reviews.llvm.org/D66524/new/ https://reviews.llvm.org/D66524 Files: docs/LangRef.rst lib/IR/InlineAsm.cpp lib/Target/AArch64/AArch64AsmPrinter.cpp lib/Target/AArch64/AArch64ISelLowering.cpp lib/Target/AArch64/AArch64InstrInfo.cpp test/CodeGen/AArch64/aarch64-sve-asm.ll
Index: test/CodeGen/AArch64/aarch64-sve-asm.ll =================================================================== --- test/CodeGen/AArch64/aarch64-sve-asm.ll +++ test/CodeGen/AArch64/aarch64-sve-asm.ll @@ -8,6 +8,7 @@ ; CHECK: [[ARG2:%[0-9]+]]:zpr = COPY $z0 ; CHECK: [[ARG3:%[0-9]+]]:zpr = COPY [[ARG2]] ; CHECK: [[ARG4:%[0-9]+]]:zpr_3b = COPY [[ARG1]] +; CHECK: INLINEASM {{.*}} [[ARG4]] define <vscale x 16 x i8> @test_svadd_i8(<vscale x 16 x i8> %Zn, <vscale x 16 x i8> %Zm) { %1 = tail call <vscale x 16 x i8> asm "add $0.b, $1.b, $2.b", "=w,w,y"(<vscale x 16 x i8> %Zn, <vscale x 16 x i8> %Zm) ret <vscale x 16 x i8> %1 @@ -18,6 +19,7 @@ ; CHECK: [[ARG2:%[0-9]+]]:zpr = COPY $z0 ; CHECK: [[ARG3:%[0-9]+]]:zpr = COPY [[ARG2]] ; CHECK: [[ARG4:%[0-9]+]]:zpr_4b = COPY [[ARG1]] +; CHECK: INLINEASM {{.*}} [[ARG4]] define <vscale x 2 x i64> @test_svsub_i64(<vscale x 2 x i64> %Zn, <vscale x 2 x i64> %Zm) { %1 = tail call <vscale x 2 x i64> asm "sub $0.d, $1.d, $2.d", "=w,w,x"(<vscale x 2 x i64> %Zn, <vscale x 2 x i64> %Zm) ret <vscale x 2 x i64> %1 @@ -28,6 +30,7 @@ ; CHECK: [[ARG2:%[0-9]+]]:zpr = COPY $z0 ; CHECK: [[ARG3:%[0-9]+]]:zpr = COPY [[ARG2]] ; CHECK: [[ARG4:%[0-9]+]]:zpr_3b = COPY [[ARG1]] +; CHECK: INLINEASM {{.*}} [[ARG4]] define <vscale x 8 x half> @test_svfmul_f16(<vscale x 8 x half> %Zn, <vscale x 8 x half> %Zm) { %1 = tail call <vscale x 8 x half> asm "fmul $0.h, $1.h, $2.h", "=w,w,y"(<vscale x 8 x half> %Zn, <vscale x 8 x half> %Zm) ret <vscale x 8 x half> %1 @@ -38,7 +41,30 @@ ; CHECK: [[ARG2:%[0-9]+]]:zpr = COPY $z0 ; CHECK: [[ARG3:%[0-9]+]]:zpr = COPY [[ARG2]] ; CHECK: [[ARG4:%[0-9]+]]:zpr_4b = COPY [[ARG1]] +; CHECK: INLINEASM {{.*}} [[ARG4]] define <vscale x 4 x float> @test_svfmul_f(<vscale x 4 x float> %Zn, <vscale x 4 x float> %Zm) { %1 = tail call <vscale x 4 x float> asm "fmul $0.s, $1.s, $2.s", "=w,w,x"(<vscale x 4 x float> %Zn, <vscale x 4 x float> %Zm) ret <vscale x 4 x float> %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_3b = COPY [[ARG3]] +; CHECK: INLINEASM {{.*}} [[ARG4]] +define <vscale x 8 x half> @test_svfadd_f16(<vscale x 16 x i1> %Pg, <vscale x 8 x half> %Zn, <vscale x 8 x half> %Zm) { + %1 = tail call <vscale x 8 x half> asm "fadd $0.h, $1/m, $2.h, $3.h", "=w,@3Upl,w,w"(<vscale x 16 x i1> %Pg, <vscale x 8 x half> %Zn, <vscale x 8 x half> %Zm) + ret <vscale x 8 x half> %1 +} + +; Function Attrs: nounwind readnone +; CHECK: [[ARG1:%[0-9]+]]:zpr = COPY $z0 +; CHECK: [[ARG2:%[0-9]+]]:ppr = COPY $p0 +; CHECK: [[ARG3:%[0-9]+]]:ppr = COPY [[ARG2]] +; CHECK: [[ARG4:%[0-9]+]]:zpr = COPY [[ARG1]] +; CHECK: INLINEASM {{.*}} [[ARG3]] +define <vscale x 4 x i32> @test_incp(<vscale x 16 x i1> %Pg, <vscale x 4 x i32> %Zn) { + %1 = tail call <vscale x 4 x i32> asm "incp $0.s, $1", "=w,@3Upa,0"(<vscale x 16 x i1> %Pg, <vscale x 4 x i32> %Zn) + ret <vscale x 4 x i32> %1 +} Index: lib/Target/AArch64/AArch64InstrInfo.cpp =================================================================== --- lib/Target/AArch64/AArch64InstrInfo.cpp +++ lib/Target/AArch64/AArch64InstrInfo.cpp @@ -2484,6 +2484,17 @@ return; } + // Copy a Predicate register by ORRing with itself. + if (AArch64::PPRRegClass.contains(DestReg) && + AArch64::PPRRegClass.contains(SrcReg)) { + assert(Subtarget.hasSVE() && "Unexpected SVE register."); + BuildMI(MBB, I, DL, get(AArch64::ORR_PPzPP), DestReg) + .addReg(SrcReg) // Pg + .addReg(SrcReg) + .addReg(SrcReg, getKillRegState(KillSrc)); + return; + } + // Copy a Z register by ORRing with itself. if (AArch64::ZPRRegClass.contains(DestReg) && AArch64::ZPRRegClass.contains(SrcReg)) { Index: lib/Target/AArch64/AArch64ISelLowering.cpp =================================================================== --- lib/Target/AArch64/AArch64ISelLowering.cpp +++ lib/Target/AArch64/AArch64ISelLowering.cpp @@ -5738,6 +5738,21 @@ return "r"; } +enum PredicateConstraint { + Upl, + Upa, + Invalid +}; + +PredicateConstraint parsePredicateConstraint(StringRef Constraint) { + PredicateConstraint P = PredicateConstraint::Invalid; + if (Constraint == "Upa") + P = PredicateConstraint::Upa; + if (Constraint == "Upl") + P = PredicateConstraint::Upl; + return P; +} + /// getConstraintType - Given a constraint letter, return the type of /// constraint it is for this target. AArch64TargetLowering::ConstraintType @@ -5767,7 +5782,9 @@ case 'S': // A symbolic address return C_Other; } - } + } else if (parsePredicateConstraint(Constraint) != + PredicateConstraint::Invalid) + return C_RegisterClass; return TargetLowering::getConstraintType(Constraint); } @@ -5798,6 +5815,10 @@ case 'z': weight = CW_Constant; break; + case 'U': + if (parsePredicateConstraint(constraint) != PredicateConstraint::Invalid) + weight = CW_Register; + break; } return weight; } @@ -5841,6 +5862,14 @@ return std::make_pair(0U, &AArch64::ZPR_3bRegClass); break; } + } else { + PredicateConstraint PC = parsePredicateConstraint(Constraint); + if (PC != PredicateConstraint::Invalid) { + assert(VT.isScalableVector()); + bool restricted = (PC == PredicateConstraint::Upl); + return restricted ? std::make_pair(0U, &AArch64::PPR_3bRegClass) + : std::make_pair(0U, &AArch64::PPRRegClass); + } } if (StringRef("{cc}").equals_lower(Constraint)) return std::make_pair(unsigned(AArch64::NZCV), &AArch64::CCRRegClass); Index: lib/Target/AArch64/AArch64AsmPrinter.cpp =================================================================== --- lib/Target/AArch64/AArch64AsmPrinter.cpp +++ lib/Target/AArch64/AArch64AsmPrinter.cpp @@ -618,6 +618,8 @@ const TargetRegisterClass *RegClass; if (AArch64::ZPRRegClass.contains(Reg)) { RegClass = &AArch64::ZPRRegClass; + } else if (AArch64::PPRRegClass.contains(Reg)) { + RegClass = &AArch64::PPRRegClass; } else { RegClass = &AArch64::FPR128RegClass; AltName = AArch64::vreg; Index: lib/IR/InlineAsm.cpp =================================================================== --- lib/IR/InlineAsm.cpp +++ lib/IR/InlineAsm.cpp @@ -181,6 +181,16 @@ // FIXME: For now assuming these are 2-character constraints. pCodes->push_back(StringRef(I+1, 2)); I += 3; + } else if (*I == '@') { + // Multi-letter constraint + ++I; + unsigned char C = static_cast<unsigned char>(*I); + assert(isdigit(C) && "Expected a digit!"); + int N = C - '0'; + assert(N > 0 && "Found a zero letter constraint!"); + ++I; + pCodes->push_back(StringRef(I, N)); + I += N; } else { // Single letter constraint. pCodes->push_back(StringRef(I, 1)); Index: docs/LangRef.rst =================================================================== --- docs/LangRef.rst +++ docs/LangRef.rst @@ -3814,6 +3814,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) +- ``Upa``: Any of the SVE predicate registers (P0 to P15) AMDGPU:
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits