<div dir="ltr"><div dir="ltr">Hi Kerry,</div><div dir="ltr"><br></div><div dir="ltr">On Tue, Sep 3, 2019 at 1:11 AM Kerry McLaughlin via llvm-commits <<a href="mailto:llvm-commits@lists.llvm.org">llvm-commits@lists.llvm.org</a>> wrote:<br></div><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">Author: kmclaughlin<br>
Date: Mon Sep  2 09:12:31 2019<br>
New Revision: 370673<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=370673&view=rev" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project?rev=370673&view=rev</a><br>
Log:<br>
[SVE][Inline-Asm] Support for SVE asm operands<br>
<br>
Summary:<br>
Adds the following inline asm constraints for SVE:<br>
  - w: SVE vector register with full range, Z0 to Z31<br>
  - x: Restricted to registers Z0 to Z15 inclusive.<br>
  - y: Restricted to registers Z0 to Z7 inclusive.<br>
<br>
This change also adds the "z" modifier to interpret a register as an SVE register.<br>
<br>
Not all of the bitconvert patterns added by this patch are used, but they have been included here for completeness.<br>
<br>
Reviewers: t.p.northover, sdesmalen, rovka, momchil.velikov, rengolin, cameron.mcinally, greened<br>
<br>
Reviewed By: sdesmalen<br>
<br>
Subscribers: javed.absar, tschuett, rkruppe, psnobl, cfe-commits, llvm-commits<br>
<br>
Tags: #llvm<br>
<br>
Differential Revision: <a href="https://reviews.llvm.org/D66302" rel="noreferrer" target="_blank">https://reviews.llvm.org/D66302</a><br>
<br>
Added:<br>
    llvm/trunk/test/CodeGen/AArch64/aarch64-sve-asm-negative.ll<br>
    llvm/trunk/test/CodeGen/AArch64/aarch64-sve-asm.ll<br>
Modified:<br>
    llvm/trunk/docs/LangRef.rst<br>
    llvm/trunk/lib/Target/AArch64/AArch64AsmPrinter.cpp<br>
    llvm/trunk/lib/Target/AArch64/AArch64ISelLowering.cpp<br>
    llvm/trunk/lib/Target/AArch64/AArch64InstrInfo.cpp<br>
    llvm/trunk/lib/Target/AArch64/AArch64SVEInstrInfo.td<br>
    llvm/trunk/test/CodeGen/AArch64/arm64-inline-asm.ll<br>
<br>
Modified: llvm/trunk/docs/LangRef.rst<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/LangRef.rst?rev=370673&r1=370672&r2=370673&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/LangRef.rst?rev=370673&r1=370672&r2=370673&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/docs/LangRef.rst (original)<br>
+++ llvm/trunk/docs/LangRef.rst Mon Sep  2 09:12:31 2019<br>
@@ -3811,8 +3811,9 @@ AArch64:<br>
   offsets). (However, LLVM currently does this for the ``m`` constraint as<br>
   well.)<br>
 - ``r``: A 32 or 64-bit integer register (W* or X*).<br>
-- ``w``: A 32, 64, or 128-bit floating-point/SIMD register.<br>
-- ``x``: A lower 128-bit floating-point/SIMD register (``V0`` to ``V15``).<br>
+- ``w``: A 32, 64, or 128-bit floating-point, SIMD or SVE vector register.<br>
+- ``x``: Like w, but restricted to registers 0 to 15 inclusive.<br>
+- ``y``: Like w, but restricted to SVE vector registers Z0 to Z7 inclusive.<br>
<br>
 AMDGPU:<br>
<br>
<br>
Modified: llvm/trunk/lib/Target/AArch64/AArch64AsmPrinter.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/AArch64AsmPrinter.cpp?rev=370673&r1=370672&r2=370673&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/AArch64AsmPrinter.cpp?rev=370673&r1=370672&r2=370673&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/Target/AArch64/AArch64AsmPrinter.cpp (original)<br>
+++ llvm/trunk/lib/Target/AArch64/AArch64AsmPrinter.cpp Mon Sep  2 09:12:31 2019<br>
@@ -150,7 +150,7 @@ private:<br>
   void printOperand(const MachineInstr *MI, unsigned OpNum, raw_ostream &O);<br>
   bool printAsmMRegister(const MachineOperand &MO, char Mode, raw_ostream &O);<br>
   bool printAsmRegInClass(const MachineOperand &MO,<br>
-                          const TargetRegisterClass *RC, bool isVector,<br>
+                          const TargetRegisterClass *RC, unsigned AltName,<br>
                           raw_ostream &O);<br>
<br>
   bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNum,<br>
@@ -530,14 +530,13 @@ bool AArch64AsmPrinter::printAsmMRegiste<br>
 // printing.<br>
 bool AArch64AsmPrinter::printAsmRegInClass(const MachineOperand &MO,<br>
                                            const TargetRegisterClass *RC,<br>
-                                           bool isVector, raw_ostream &O) {<br>
+                                           unsigned AltName, raw_ostream &O) {<br>
   assert(MO.isReg() && "Should only get here with a register!");<br>
   const TargetRegisterInfo *RI = STI->getRegisterInfo();<br>
   Register Reg = MO.getReg();<br>
   unsigned RegToPrint = RC->getRegister(RI->getEncodingValue(Reg));<br>
   assert(RI->regsOverlap(RegToPrint, Reg));<br>
-  O << AArch64InstPrinter::getRegisterName(<br>
-           RegToPrint, isVector ? AArch64::vreg : AArch64::NoRegAltName);<br>
+  O << AArch64InstPrinter::getRegisterName(RegToPrint, AltName);<br>
   return false;<br>
 }<br>
<br>
@@ -573,6 +572,7 @@ bool AArch64AsmPrinter::PrintAsmOperand(<br>
     case 's': // Print S register.<br>
     case 'd': // Print D register.<br>
     case 'q': // Print Q register.<br>
+    case 'z': // Print Z register.<br>
       if (MO.isReg()) {<br>
         const TargetRegisterClass *RC;<br>
         switch (ExtraCode[0]) {<br>
@@ -591,10 +591,13 @@ bool AArch64AsmPrinter::PrintAsmOperand(<br>
         case 'q':<br>
           RC = &AArch64::FPR128RegClass;<br>
           break;<br>
+        case 'z':<br>
+          RC = &AArch64::ZPRRegClass;<br>
+          break;<br>
         default:<br>
           return true;<br>
         }<br>
-        return printAsmRegInClass(MO, RC, false /* vector */, O);<br>
+        return printAsmRegInClass(MO, RC, AArch64::NoRegAltName, O);<br>
       }<br>
       printOperand(MI, OpNum, O);<br>
       return false;<br>
@@ -611,9 +614,17 @@ bool AArch64AsmPrinter::PrintAsmOperand(<br>
         AArch64::GPR64allRegClass.contains(Reg))<br>
       return printAsmMRegister(MO, 'x', O);<br>
<br>
+    unsigned AltName = AArch64::NoRegAltName;<br>
+    const TargetRegisterClass *RegClass;<br>
+    if (AArch64::ZPRRegClass.contains(Reg)) {<br>
+      RegClass = &AArch64::ZPRRegClass;<br>
+    } else {<br>
+      RegClass = &AArch64::FPR128RegClass;<br>
+      AltName = AArch64::vreg;<br>
+    }<br>
+<br>
     // If this is a b, h, s, d, or q register, print it as a v register.<br>
-    return printAsmRegInClass(MO, &AArch64::FPR128RegClass, true /* vector */,<br>
-                              O);<br>
+    return printAsmRegInClass(MO, RegClass, AltName, O);<br>
   }<br>
<br>
   printOperand(MI, OpNum, O);<br>
<br>
Modified: llvm/trunk/lib/Target/AArch64/AArch64ISelLowering.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/AArch64ISelLowering.cpp?rev=370673&r1=370672&r2=370673&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/AArch64ISelLowering.cpp?rev=370673&r1=370672&r2=370673&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/Target/AArch64/AArch64ISelLowering.cpp (original)<br>
+++ llvm/trunk/lib/Target/AArch64/AArch64ISelLowering.cpp Mon Sep  2 09:12:31 2019<br>
@@ -5748,6 +5748,7 @@ AArch64TargetLowering::getConstraintType<br>
       break;<br>
     case 'x':<br>
     case 'w':<br>
+    case 'y':<br>
       return C_RegisterClass;<br>
     // An address with a single base register. Due to the way we<br>
     // currently handle addresses it is the same as 'r'.<br>
@@ -5790,6 +5791,7 @@ AArch64TargetLowering::getSingleConstrai<br>
     break;<br>
   case 'x':<br>
   case 'w':<br>
+  case 'y':<br>
     if (type->isFloatingPointTy() || type->isVectorTy())<br>
       weight = CW_Register;<br>
     break;<br>
@@ -5812,6 +5814,8 @@ AArch64TargetLowering::getRegForInlineAs<br>
     case 'w':<br>
       if (!Subtarget->hasFPARMv8())<br>
         break;<br>
+      if (VT.isScalableVector())<br>
+        return std::make_pair(0U, &AArch64::ZPRRegClass);<br>
       if (VT.getSizeInBits() == 16)<br>
         return std::make_pair(0U, &AArch64::FPR16RegClass);<br>
       if (VT.getSizeInBits() == 32)<br>
@@ -5826,8 +5830,15 @@ AArch64TargetLowering::getRegForInlineAs<br>
     case 'x':<br>
       if (!Subtarget->hasFPARMv8())<br>
         break;<br>
+      if (VT.isScalableVector())<br>
+        return std::make_pair(0U, &AArch64::ZPR_4bRegClass);<br>
       if (VT.getSizeInBits() == 128)<br>
         return std::make_pair(0U, &AArch64::FPR128_loRegClass);<br>
+    case 'y':<br>
+      if (!Subtarget->hasFPARMv8())<br>
+        break;<br>
+      if (VT.isScalableVector())<br>
+        return std::make_pair(0U, &AArch64::ZPR_3bRegClass);<br>
       break;<br></blockquote><div><br></div><div>This part of the change caused -Wimplicit-fallthrough to be triggered. Can you either add `break` or `LLVM_FALLTHROUGH` before `case 'y'`?</div><div><br></div><div>(Since all tests pass as-is and with a `break`, I couldn't figure out which is expected. Maybe the test coverage is not enough?)</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
     }<br>
   }<br>
<br>
Modified: llvm/trunk/lib/Target/AArch64/AArch64InstrInfo.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/AArch64InstrInfo.cpp?rev=370673&r1=370672&r2=370673&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/AArch64InstrInfo.cpp?rev=370673&r1=370672&r2=370673&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/Target/AArch64/AArch64InstrInfo.cpp (original)<br>
+++ llvm/trunk/lib/Target/AArch64/AArch64InstrInfo.cpp Mon Sep  2 09:12:31 2019<br>
@@ -2484,6 +2484,16 @@ void AArch64InstrInfo::copyPhysReg(Machi<br>
     return;<br>
   }<br>
<br>
+  // Copy a Z register by ORRing with itself.<br>
+  if (AArch64::ZPRRegClass.contains(DestReg) &&<br>
+      AArch64::ZPRRegClass.contains(SrcReg)) {<br>
+    assert(Subtarget.hasSVE() && "Unexpected SVE register.");<br>
+    BuildMI(MBB, I, DL, get(AArch64::ORR_ZZZ), DestReg)<br>
+      .addReg(SrcReg)<br>
+      .addReg(SrcReg, getKillRegState(KillSrc));<br>
+    return;<br>
+  }<br>
+<br>
   if (AArch64::GPR64spRegClass.contains(DestReg) &&<br>
       (AArch64::GPR64spRegClass.contains(SrcReg) || SrcReg == AArch64::XZR)) {<br>
     if (DestReg == AArch64::SP || SrcReg == AArch64::SP) {<br>
<br>
Modified: llvm/trunk/lib/Target/AArch64/AArch64SVEInstrInfo.td<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/AArch64SVEInstrInfo.td?rev=370673&r1=370672&r2=370673&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/AArch64SVEInstrInfo.td?rev=370673&r1=370672&r2=370673&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/Target/AArch64/AArch64SVEInstrInfo.td (original)<br>
+++ llvm/trunk/lib/Target/AArch64/AArch64SVEInstrInfo.td Mon Sep  2 09:12:31 2019<br>
@@ -1020,6 +1020,56 @@ let Predicates = [HasSVE] in {<br>
                   (FCMGT_PPzZZ_S PPR32:$Zd, PPR3bAny:$Pg, ZPR32:$Zn, ZPR32:$Zm), 0>;<br>
   def : InstAlias<"fcmlt $Zd, $Pg/z, $Zm, $Zn",<br>
                   (FCMGT_PPzZZ_D PPR64:$Zd, PPR3bAny:$Pg, ZPR64:$Zn, ZPR64:$Zm), 0>;<br>
+<br>
+  def : Pat<(nxv16i8 (bitconvert (nxv8i16 ZPR:$src))), (nxv16i8 ZPR:$src)>;<br>
+  def : Pat<(nxv16i8 (bitconvert (nxv4i32 ZPR:$src))), (nxv16i8 ZPR:$src)>;<br>
+  def : Pat<(nxv16i8 (bitconvert (nxv2i64 ZPR:$src))), (nxv16i8 ZPR:$src)>;<br>
+  def : Pat<(nxv16i8 (bitconvert (nxv8f16 ZPR:$src))), (nxv16i8 ZPR:$src)>;<br>
+  def : Pat<(nxv16i8 (bitconvert (nxv4f32 ZPR:$src))), (nxv16i8 ZPR:$src)>;<br>
+  def : Pat<(nxv16i8 (bitconvert (nxv2f64 ZPR:$src))), (nxv16i8 ZPR:$src)>;<br>
+<br>
+  def : Pat<(nxv8i16 (bitconvert (nxv16i8 ZPR:$src))), (nxv8i16 ZPR:$src)>;<br>
+  def : Pat<(nxv8i16 (bitconvert (nxv4i32 ZPR:$src))), (nxv8i16 ZPR:$src)>;<br>
+  def : Pat<(nxv8i16 (bitconvert (nxv2i64 ZPR:$src))), (nxv8i16 ZPR:$src)>;<br>
+  def : Pat<(nxv8i16 (bitconvert (nxv8f16 ZPR:$src))), (nxv8i16 ZPR:$src)>;<br>
+  def : Pat<(nxv8i16 (bitconvert (nxv4f32 ZPR:$src))), (nxv8i16 ZPR:$src)>;<br>
+  def : Pat<(nxv8i16 (bitconvert (nxv2f64 ZPR:$src))), (nxv8i16 ZPR:$src)>;<br>
+<br>
+  def : Pat<(nxv4i32 (bitconvert (nxv16i8 ZPR:$src))), (nxv4i32 ZPR:$src)>;<br>
+  def : Pat<(nxv4i32 (bitconvert (nxv8i16 ZPR:$src))), (nxv4i32 ZPR:$src)>;<br>
+  def : Pat<(nxv4i32 (bitconvert (nxv2i64 ZPR:$src))), (nxv4i32 ZPR:$src)>;<br>
+  def : Pat<(nxv4i32 (bitconvert (nxv8f16 ZPR:$src))), (nxv4i32 ZPR:$src)>;<br>
+  def : Pat<(nxv4i32 (bitconvert (nxv4f32 ZPR:$src))), (nxv4i32 ZPR:$src)>;<br>
+  def : Pat<(nxv4i32 (bitconvert (nxv2f64 ZPR:$src))), (nxv4i32 ZPR:$src)>;<br>
+<br>
+  def : Pat<(nxv2i64 (bitconvert (nxv16i8 ZPR:$src))), (nxv2i64 ZPR:$src)>;<br>
+  def : Pat<(nxv2i64 (bitconvert (nxv8i16 ZPR:$src))), (nxv2i64 ZPR:$src)>;<br>
+  def : Pat<(nxv2i64 (bitconvert (nxv4i32 ZPR:$src))), (nxv2i64 ZPR:$src)>;<br>
+  def : Pat<(nxv2i64 (bitconvert (nxv8f16 ZPR:$src))), (nxv2i64 ZPR:$src)>;<br>
+  def : Pat<(nxv2i64 (bitconvert (nxv4f32 ZPR:$src))), (nxv2i64 ZPR:$src)>;<br>
+  def : Pat<(nxv2i64 (bitconvert (nxv2f64 ZPR:$src))), (nxv2i64 ZPR:$src)>;<br>
+<br>
+  def : Pat<(nxv8f16 (bitconvert (nxv16i8 ZPR:$src))), (nxv8f16 ZPR:$src)>;<br>
+  def : Pat<(nxv8f16 (bitconvert (nxv8i16 ZPR:$src))), (nxv8f16 ZPR:$src)>;<br>
+  def : Pat<(nxv8f16 (bitconvert (nxv4i32 ZPR:$src))), (nxv8f16 ZPR:$src)>;<br>
+  def : Pat<(nxv8f16 (bitconvert (nxv2i64 ZPR:$src))), (nxv8f16 ZPR:$src)>;<br>
+  def : Pat<(nxv8f16 (bitconvert (nxv4f32 ZPR:$src))), (nxv8f16 ZPR:$src)>;<br>
+  def : Pat<(nxv8f16 (bitconvert (nxv2f64 ZPR:$src))), (nxv8f16 ZPR:$src)>;<br>
+<br>
+  def : Pat<(nxv4f32 (bitconvert (nxv16i8 ZPR:$src))), (nxv4f32 ZPR:$src)>;<br>
+  def : Pat<(nxv4f32 (bitconvert (nxv8i16 ZPR:$src))), (nxv4f32 ZPR:$src)>;<br>
+  def : Pat<(nxv4f32 (bitconvert (nxv4i32 ZPR:$src))), (nxv4f32 ZPR:$src)>;<br>
+  def : Pat<(nxv4f32 (bitconvert (nxv2i64 ZPR:$src))), (nxv4f32 ZPR:$src)>;<br>
+  def : Pat<(nxv4f32 (bitconvert (nxv8f16 ZPR:$src))), (nxv4f32 ZPR:$src)>;<br>
+  def : Pat<(nxv4f32 (bitconvert (nxv2f64 ZPR:$src))), (nxv4f32 ZPR:$src)>;<br>
+<br>
+  def : Pat<(nxv2f64 (bitconvert (nxv16i8 ZPR:$src))), (nxv2f64 ZPR:$src)>;<br>
+  def : Pat<(nxv2f64 (bitconvert (nxv8i16 ZPR:$src))), (nxv2f64 ZPR:$src)>;<br>
+  def : Pat<(nxv2f64 (bitconvert (nxv4i32 ZPR:$src))), (nxv2f64 ZPR:$src)>;<br>
+  def : Pat<(nxv2f64 (bitconvert (nxv2i64 ZPR:$src))), (nxv2f64 ZPR:$src)>;<br>
+  def : Pat<(nxv2f64 (bitconvert (nxv8f16 ZPR:$src))), (nxv2f64 ZPR:$src)>;<br>
+  def : Pat<(nxv2f64 (bitconvert (nxv4f32 ZPR:$src))), (nxv2f64 ZPR:$src)>;<br>
+<br>
 }<br>
<br>
 let Predicates = [HasSVE2] in {<br>
<br>
Added: llvm/trunk/test/CodeGen/AArch64/aarch64-sve-asm-negative.ll<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/AArch64/aarch64-sve-asm-negative.ll?rev=370673&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/AArch64/aarch64-sve-asm-negative.ll?rev=370673&view=auto</a><br>
==============================================================================<br>
--- llvm/trunk/test/CodeGen/AArch64/aarch64-sve-asm-negative.ll (added)<br>
+++ llvm/trunk/test/CodeGen/AArch64/aarch64-sve-asm-negative.ll Mon Sep  2 09:12:31 2019<br>
@@ -0,0 +1,12 @@<br>
+; RUN: not llc -mtriple aarch64-none-linux-gnu -mattr=+neon -o %t.s -filetype=asm %s 2>&1 | FileCheck %s<br>
+<br>
+; The 'y' constraint only applies to SVE vector registers (Z0-Z7)<br>
+; The test below ensures that we get an appropriate error should the<br>
+; constraint be used with a Neon register.<br>
+<br>
+; Function Attrs: nounwind readnone<br>
+; CHECK: error: couldn't allocate input reg for constraint 'y'<br>
+define <4 x i32> @test_neon(<4 x i32> %in1, <4 x i32> %in2) {<br>
+  %1 = tail call <4 x i32> asm "add $0.4s, $1.4s, $2.4s", "=w,w,y"(<4 x i32> %in1, <4 x i32> %in2)<br>
+  ret <4 x i32> %1<br>
+}<br>
<br>
Added: llvm/trunk/test/CodeGen/AArch64/aarch64-sve-asm.ll<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/AArch64/aarch64-sve-asm.ll?rev=370673&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/AArch64/aarch64-sve-asm.ll?rev=370673&view=auto</a><br>
==============================================================================<br>
--- llvm/trunk/test/CodeGen/AArch64/aarch64-sve-asm.ll (added)<br>
+++ llvm/trunk/test/CodeGen/AArch64/aarch64-sve-asm.ll Mon Sep  2 09:12:31 2019<br>
@@ -0,0 +1,44 @@<br>
+; RUN: llc < %s -mtriple aarch64-none-linux-gnu -mattr=+sve -stop-after=finalize-isel | FileCheck %s --check-prefix=CHECK<br>
+<br>
+target datalayout = "e-m:e-i64:64-i128:128-n32:64-S128"<br>
+target triple = "aarch64-none-linux-gnu"<br>
+<br>
+; Function Attrs: nounwind readnone<br>
+; CHECK: [[ARG1:%[0-9]+]]:zpr = COPY $z1<br>
+; CHECK: [[ARG2:%[0-9]+]]:zpr = COPY $z0<br>
+; CHECK: [[ARG3:%[0-9]+]]:zpr = COPY [[ARG2]]<br>
+; CHECK: [[ARG4:%[0-9]+]]:zpr_3b = COPY [[ARG1]]<br>
+define <vscale x 16 x i8> @test_svadd_i8(<vscale x 16 x i8> %Zn, <vscale x 16 x i8> %Zm) {<br>
+  %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)<br>
+  ret <vscale x 16 x i8> %1<br>
+}<br>
+<br>
+; Function Attrs: nounwind readnone<br>
+; CHECK: [[ARG1:%[0-9]+]]:zpr = COPY $z1<br>
+; CHECK: [[ARG2:%[0-9]+]]:zpr = COPY $z0<br>
+; CHECK: [[ARG3:%[0-9]+]]:zpr = COPY [[ARG2]]<br>
+; CHECK: [[ARG4:%[0-9]+]]:zpr_4b = COPY [[ARG1]]<br>
+define <vscale x 2 x i64> @test_svsub_i64(<vscale x 2 x i64> %Zn, <vscale x 2 x i64> %Zm) {<br>
+  %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)<br>
+  ret <vscale x 2 x i64> %1<br>
+}<br>
+<br>
+; Function Attrs: nounwind readnone<br>
+; CHECK: [[ARG1:%[0-9]+]]:zpr = COPY $z1<br>
+; CHECK: [[ARG2:%[0-9]+]]:zpr = COPY $z0<br>
+; CHECK: [[ARG3:%[0-9]+]]:zpr = COPY [[ARG2]]<br>
+; CHECK: [[ARG4:%[0-9]+]]:zpr_3b = COPY [[ARG1]]<br>
+define <vscale x 8 x half> @test_svfmul_f16(<vscale x 8 x half> %Zn, <vscale x 8 x half> %Zm) {<br>
+  %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)<br>
+  ret <vscale x 8 x half> %1<br>
+}<br>
+<br>
+; Function Attrs: nounwind readnone<br>
+; CHECK: [[ARG1:%[0-9]+]]:zpr = COPY $z1<br>
+; CHECK: [[ARG2:%[0-9]+]]:zpr = COPY $z0<br>
+; CHECK: [[ARG3:%[0-9]+]]:zpr = COPY [[ARG2]]<br>
+; CHECK: [[ARG4:%[0-9]+]]:zpr_4b = COPY [[ARG1]]<br>
+define <vscale x 4 x float> @test_svfmul_f(<vscale x 4 x float> %Zn, <vscale x 4 x float> %Zm) {<br>
+  %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)<br>
+  ret <vscale x 4 x float> %1<br>
+}<br>
<br>
Modified: llvm/trunk/test/CodeGen/AArch64/arm64-inline-asm.ll<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/AArch64/arm64-inline-asm.ll?rev=370673&r1=370672&r2=370673&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/AArch64/arm64-inline-asm.ll?rev=370673&r1=370672&r2=370673&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/test/CodeGen/AArch64/arm64-inline-asm.ll (original)<br>
+++ llvm/trunk/test/CodeGen/AArch64/arm64-inline-asm.ll Mon Sep  2 09:12:31 2019<br>
@@ -138,6 +138,8 @@ entry:<br>
   %a = alloca [2 x float], align 4<br>
   %arraydecay = getelementptr inbounds [2 x float], [2 x float]* %a, i32 0, i32 0<br>
   %0 = load <2 x float>, <2 x float>* %data, align 8<br>
+  call void asm sideeffect "ldr ${1:z}, [$0]\0A", "r,w"(float* %arraydecay, <2 x float> %0) nounwind<br>
+  ; CHECK: ldr {{z[0-9]+}}, [{{x[0-9]+}}]<br>
   call void asm sideeffect "ldr ${1:q}, [$0]\0A", "r,w"(float* %arraydecay, <2 x float> %0) nounwind<br>
   ; CHECK: ldr {{q[0-9]+}}, [{{x[0-9]+}}]<br>
   call void asm sideeffect "ldr ${1:d}, [$0]\0A", "r,w"(float* %arraydecay, <2 x float> %0) nounwind<br>
<br>
<br>
_______________________________________________<br>
llvm-commits mailing list<br>
<a href="mailto:llvm-commits@lists.llvm.org" target="_blank">llvm-commits@lists.llvm.org</a><br>
<a href="https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits" rel="noreferrer" target="_blank">https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits</a><br>
</blockquote></div></div>