[PATCH] D66524: [SVE][Inline-Asm] Add constraints for SVE predicate registers

2019-09-16 Thread Kerry McLaughlin via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rL371967: [SVE][Inline-Asm] Add constraints for SVE predicate 
registers (authored by kmclaughlin, committed by ).

Changed prior to commit:
  https://reviews.llvm.org/D66524?vs=219526=220299#toc

Repository:
  rL LLVM

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D66524/new/

https://reviews.llvm.org/D66524

Files:
  llvm/trunk/docs/LangRef.rst
  llvm/trunk/lib/IR/InlineAsm.cpp
  llvm/trunk/lib/Target/AArch64/AArch64AsmPrinter.cpp
  llvm/trunk/lib/Target/AArch64/AArch64ISelLowering.cpp
  llvm/trunk/lib/Target/AArch64/AArch64InstrInfo.cpp
  llvm/trunk/test/CodeGen/AArch64/aarch64-sve-asm.ll

Index: llvm/trunk/lib/IR/InlineAsm.cpp
===
--- llvm/trunk/lib/IR/InlineAsm.cpp
+++ llvm/trunk/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(*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: llvm/trunk/lib/Target/AArch64/AArch64AsmPrinter.cpp
===
--- llvm/trunk/lib/Target/AArch64/AArch64AsmPrinter.cpp
+++ llvm/trunk/lib/Target/AArch64/AArch64AsmPrinter.cpp
@@ -618,6 +618,8 @@
 const TargetRegisterClass *RegClass;
 if (AArch64::ZPRRegClass.contains(Reg)) {
   RegClass = ::ZPRRegClass;
+} else if (AArch64::PPRRegClass.contains(Reg)) {
+  RegClass = ::PPRRegClass;
 } else {
   RegClass = ::FPR128RegClass;
   AltName = AArch64::vreg;
Index: llvm/trunk/lib/Target/AArch64/AArch64InstrInfo.cpp
===
--- llvm/trunk/lib/Target/AArch64/AArch64InstrInfo.cpp
+++ llvm/trunk/lib/Target/AArch64/AArch64InstrInfo.cpp
@@ -2507,6 +2507,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: llvm/trunk/lib/Target/AArch64/AArch64ISelLowering.cpp
===
--- llvm/trunk/lib/Target/AArch64/AArch64ISelLowering.cpp
+++ llvm/trunk/lib/Target/AArch64/AArch64ISelLowering.cpp
@@ -5837,6 +5837,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
@@ -5866,7 +5881,9 @@
 case 'S': // A symbolic address
   return C_Other;
 }
-  }
+  } else if (parsePredicateConstraint(Constraint) !=
+ PredicateConstraint::Invalid)
+  return C_RegisterClass;
   return TargetLowering::getConstraintType(Constraint);
 }
 
@@ -5897,6 +5914,10 @@
   case 'z':
 weight = CW_Constant;
 break;
+  case 'U':
+if (parsePredicateConstraint(constraint) != PredicateConstraint::Invalid)
+  weight = CW_Register;
+break;
   }
   return weight;
 }
@@ -5941,6 +5962,14 @@
 return std::make_pair(0U, ::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, ::PPR_3bRegClass)
+  : std::make_pair(0U, ::PPRRegClass);
+}
   }
   if (StringRef("{cc}").equals_lower(Constraint))
 return std::make_pair(unsigned(AArch64::NZCV), ::CCRRegClass);
Index: llvm/trunk/docs/LangRef.rst
===
--- llvm/trunk/docs/LangRef.rst
+++ llvm/trunk/docs/LangRef.rst
@@ -3825,6 +3825,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 

[PATCH] D66524: [SVE][Inline-Asm] Add constraints for SVE predicate registers

2019-09-16 Thread Diana Picus via Phabricator via cfe-commits
rovka accepted this revision.
rovka added a comment.
This revision is now accepted and ready to land.

I think all the outstanding comments have been addressed. LGTM.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D66524/new/

https://reviews.llvm.org/D66524



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D66524: [SVE][Inline-Asm] Add constraints for SVE predicate registers

2019-09-10 Thread Kerry McLaughlin via Phabricator via cfe-commits
kmclaughlin marked 3 inline comments as done.
kmclaughlin added inline comments.



Comment at: docs/LangRef.rst:3818
+- ``Upl``: One of the low eight SVE predicate registers (P0 to P7)
+- ``Upa``: Any of the SVE predicate registers (P0 to P15)
 

greened wrote:
> What do these names mean?  " predicate lower|all?"  I see they are 
> the names used in gcc, so I guess it makes sense to use them here.  Are these 
> names used in the SVE architecture manual somewhere?  I cannot find them.
The length of the constraint depends on the first letter, and for AArch64 'U' 
was chosen to indicate a 3-letter constraint. These are not in the SVE 
architecture manual as they are only for compatibility with GCC inline asm (see 
https://gcc.gnu.org/onlinedocs/gcc/Machine-Constraints.html#Machine-Constraints)



Comment at: lib/Target/AArch64/AArch64ISelLowering.cpp:5747
+
+PredicateConstraint isPredicateConstraint(StringRef Constraint) {
+  PredicateConstraint P = PredicateConstraint::Invalid;

greened wrote:
> rovka wrote:
> > Nit: I think get- or parsePredicateConstraint reads better, since this 
> > doesn't return a simple yes/no answer.
> +1.
Thanks for the suggestion @rovka - I have changed this to 
parsePredicateConstraint


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D66524/new/

https://reviews.llvm.org/D66524



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D66524: [SVE][Inline-Asm] Add constraints for SVE predicate registers

2019-09-10 Thread Kerry McLaughlin via Phabricator via cfe-commits
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  @test_svadd_i8( %Zn,  %Zm) {
   %1 = tail call  asm "add $0.b, $1.b, $2.b", "=w,w,y"( %Zn,  %Zm)
   ret  %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  @test_svsub_i64( %Zn,  %Zm) {
   %1 = tail call  asm "sub $0.d, $1.d, $2.d", "=w,w,x"( %Zn,  %Zm)
   ret  %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  @test_svfmul_f16( %Zn,  %Zm) {
   %1 = tail call  asm "fmul $0.h, $1.h, $2.h", "=w,w,y"( %Zn,  %Zm)
   ret  %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  @test_svfmul_f( %Zn,  %Zm) {
   %1 = tail call  asm "fmul $0.s, $1.s, $2.s", "=w,w,x"( %Zn,  %Zm)
   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_3b = COPY [[ARG3]]
+; CHECK: INLINEASM {{.*}} [[ARG4]]
+define  @test_svfadd_f16( %Pg,  %Zn,  %Zm) {
+  %1 = tail call  asm "fadd $0.h, $1/m, $2.h, $3.h", "=w,@3Upl,w,w"( %Pg,  %Zn,  %Zm)
+  ret  %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  @test_incp( %Pg,  %Zn) {
+  %1 = tail call  asm "incp $0.s, $1", "=w,@3Upa,0"( %Pg,  %Zn)
+  ret  %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, ::ZPR_3bRegClass);
   break;
 }
+  } else {
+PredicateConstraint PC = parsePredicateConstraint(Constraint);
+if (PC != 

[PATCH] D66524: [SVE][Inline-Asm] Add constraints for SVE predicate registers

2019-09-03 Thread David Greene via Phabricator via cfe-commits
greened added inline comments.



Comment at: docs/LangRef.rst:3818
+- ``Upl``: One of the low eight SVE predicate registers (P0 to P7)
+- ``Upa``: Any of the SVE predicate registers (P0 to P15)
 

What do these names mean?  " predicate lower|all?"  I see they are 
the names used in gcc, so I guess it makes sense to use them here.  Are these 
names used in the SVE architecture manual somewhere?  I cannot find them.



Comment at: lib/Target/AArch64/AArch64ISelLowering.cpp:5747
+
+PredicateConstraint isPredicateConstraint(StringRef Constraint) {
+  PredicateConstraint P = PredicateConstraint::Invalid;

rovka wrote:
> Nit: I think get- or parsePredicateConstraint reads better, since this 
> doesn't return a simple yes/no answer.
+1.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D66524/new/

https://reviews.llvm.org/D66524



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D66524: [SVE][Inline-Asm] Add constraints for SVE predicate registers

2019-09-02 Thread Diana Picus via Phabricator via cfe-commits
rovka added a comment.

Just some drive-by suggestions :)




Comment at: lib/Target/AArch64/AArch64ISelLowering.cpp:5747
+
+PredicateConstraint isPredicateConstraint(StringRef Constraint) {
+  PredicateConstraint P = PredicateConstraint::Invalid;

Nit: I think get- or parsePredicateConstraint reads better, since this doesn't 
return a simple yes/no answer.



Comment at: test/CodeGen/AArch64/aarch64-sve-asm.ll:50
+; CHECK: [[ARG3:%[0-9]+]]:ppr = COPY $p0
+; CHECK: [[ARG4:%[0-9]+]]:ppr_3b = COPY [[ARG3]]
+define  @test_svfadd_f16( %Pg,  %Zn,  %Zm) {

Nit: I would be a bit pedantic here and also check that they are used for the 
inline asm.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D66524/new/

https://reviews.llvm.org/D66524



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D66524: [SVE][Inline-Asm] Add constraints for SVE predicate registers

2019-08-30 Thread Kerry McLaughlin via Phabricator via cfe-commits
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  asm "fmul $0.s, $1.s, $2.s", "=w,w,x"( %Zn,  %Zm)
   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_3b = COPY [[ARG3]]
+define  @test_svfadd_f16( %Pg,  %Zn,  %Zm) {
+  %1 = tail call  asm "fadd $0.h, $1/m, $2.h, $3.h", "=w,@3Upl,w,w"( %Pg,  %Zn,  %Zm)
+  ret  %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  @test_incp( %Pg,  %Zn) {
+  %1 = tail call  asm "incp $0.s, $1", "=w,@3Upa,0"( %Pg,  %Zn)
+  ret  %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, ::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, ::PPR_3bRegClass)
+  : std::make_pair(0U, ::PPRRegClass);
+}
   }
   if (StringRef("{cc}").equals_lower(Constraint))
 return std::make_pair(unsigned(AArch64::NZCV), ::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 = ::ZPRRegClass;
+} else if (AArch64::PPRRegClass.contains(Reg)) {
+  RegClass = ::PPRRegClass;
 } else {
   RegClass = ::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));
 

[PATCH] D66524: [SVE][Inline-Asm] Add constraints for SVE predicate registers

2019-08-21 Thread Sander de Smalen via Phabricator via cfe-commits
sdesmalen added inline comments.



Comment at: lib/IR/InlineAsm.cpp:188
+  unsigned char C = static_cast(*I);
+  assert(isdigit(C) && "Not a single digit!");
+  int N = C - '0';

`"Expected a digit"` seems more appropriate, since this code is only testing a 
single character.



Comment at: lib/IR/InlineAsm.cpp:192
+  ++I;
+  pCodes->push_back(std::string(I, I+N));
+  I += N;

StringRef can be used here instead of std::string.



Comment at: lib/Target/AArch64/AArch64ISelLowering.cpp:5803
+  case 'U':
+if (constraint[1] == 'p' && (constraint[2] == 'l' || constraint[2] == 'a'))
+  weight = CW_Register;

This is missing a check that `Constraint.size() == 3`. Or perhaps it is even 
better to split this code out into a separate function, because this patch 
writes out the condition three times. Maybe something like  
`PredicateConstraint isPredicateConstraint(StringRef S)`, where 
`PredicateConstraint` is an enum.


Repository:
  rL LLVM

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D66524/new/

https://reviews.llvm.org/D66524



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D66524: [SVE][Inline-Asm] Add constraints for SVE predicate registers

2019-08-21 Thread Kerry McLaughlin via Phabricator via cfe-commits
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 
 inclusive
- Upa: SVE predicate register with full range, P0 to 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  %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  @test_svfadd_f16( %Pg,  %Zn,  %Zm) {
+  %1 = tail call  asm "fadd $0.h, $1/m, $2.h, $3.h", "=w,@3Upl,w,w"( %Pg,  %Zn,  %Zm)
+  ret  %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  @test_incp( %Pg,  %Zn) {
+  %1 = tail call  asm "incp $0.s, $1", "=w,@3Upa,0"( %Pg,  %Zn)
+  ret  %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, ::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, ::PPR_3bRegClass)
+: std::make_pair(0U, ::PPRRegClass);
   }
   if (StringRef("{cc}").equals_lower(Constraint))
 return std::make_pair(unsigned(AArch64::NZCV), ::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 = ::ZPRRegClass;
   hasAltName = false;
+} else if (AArch64::PPRRegClass.contains(Reg)) {
+  RegClass = ::PPRRegClass;
+  hasAltName = false;
 } else {
   RegClass = ::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(*I);
+  assert(isdigit(C) &&