kmclaughlin updated this revision to Diff 218071.
kmclaughlin added a comment.
- Added isPredicateConstraint function to AArch64ISelLowering.cpp, which
returns Upl, Upa or Invalid. This is used to replace some repeated checks of
the predicate type
- Minor changes to InlineAsm.cpp
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
@@ -42,3 +42,23 @@
%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]]
+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
+}
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 isPredicateConstraint(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,8 @@
case 'S': // A symbolic address
return C_Other;
}
- }
+ } else if (isPredicateConstraint(Constraint) != PredicateConstraint::Invalid)
+ return C_RegisterClass;
return TargetLowering::getConstraintType(Constraint);
}
@@ -5798,6 +5814,10 @@
case 'z':
weight = CW_Constant;
break;
+ case 'U':
+ if (isPredicateConstraint(constraint) != PredicateConstraint::Invalid)
+ weight = CW_Register;
+ break;
}
return weight;
}
@@ -5841,6 +5861,14 @@
return std::make_pair(0U, &AArch64::ZPR_3bRegClass);
break;
}
+ } else {
+ PredicateConstraint PC = isPredicateConstraint(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
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits