kmclaughlin created this revision. kmclaughlin added reviewers: t.p.northover, sdesmalen, rovka, momchil.velikov, cameron.mcinally, greened. Herald added subscribers: psnobl, rkruppe, tschuett, javed.absar. Herald added a reviewer: rengolin. Herald added a project: LLVM. kmclaughlin added a parent revision: D66302: [SVE][Inline-Asm] Support for SVE asm operands.
Adds the following inline asm constraints for SVE: - Upl: One of the low eight SVE predicate registers, P0 to P7 <https://reviews.llvm.org/P7> inclusive - Upa: SVE predicate register with full range, P0 to P15 <https://reviews.llvm.org/P15> Repository: rL LLVM 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 @@ -43,4 +43,24 @@ 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]] +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]] +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 +} + !0 = !{i32 188, i32 210} Index: lib/Target/AArch64/AArch64InstrInfo.cpp =================================================================== --- lib/Target/AArch64/AArch64InstrInfo.cpp +++ lib/Target/AArch64/AArch64InstrInfo.cpp @@ -2486,6 +2486,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 @@ -5764,6 +5764,10 @@ case 'S': // A symbolic address return C_Other; } + } else if (Constraint.size() == 3 && Constraint[0] == 'U' + && Constraint[1] == 'p' + && (Constraint[2] == 'l' || Constraint[2] == 'a')) { + return C_RegisterClass; } return TargetLowering::getConstraintType(Constraint); } @@ -5795,6 +5799,10 @@ case 'z': weight = CW_Constant; break; + case 'U': + if (constraint[1] == 'p' && (constraint[2] == 'l' || constraint[2] == 'a')) + weight = CW_Register; + break; } return weight; } @@ -5838,6 +5846,13 @@ return std::make_pair(0U, &AArch64::ZPR_3bRegClass); break; } + } else if (Constraint.size() == 3 && Constraint[0] == 'U' + && Constraint[1] == 'p' + && (Constraint[2] == 'l' || Constraint[2] == 'a')) { + assert(VT.isScalableVector()); + bool restricted = (Constraint[2] == 'l'); + 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 @@ -620,6 +620,9 @@ if (AArch64::ZPRRegClass.contains(Reg)) { RegClass = &AArch64::ZPRRegClass; hasAltName = false; + } else if (AArch64::PPRRegClass.contains(Reg)) { + RegClass = &AArch64::PPRRegClass; + hasAltName = false; } else { RegClass = &AArch64::FPR128RegClass; hasAltName = true; 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) && "Not a single digit!"); + int N = C - '0'; + assert(N > 0 && "Found a zero letter constraint!"); + ++I; + pCodes->push_back(std::string(I, 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