[llvm] r326609 - [SystemZ] Support vector registers in inline asm

Ulrich Weigand via llvm-commits llvm-commits at lists.llvm.org
Fri Mar 2 12:36:34 PST 2018


Author: uweigand
Date: Fri Mar  2 12:36:34 2018
New Revision: 326609

URL: http://llvm.org/viewvc/llvm-project?rev=326609&view=rev
Log:
[SystemZ] Support vector registers in inline asm

This adds support for specifying vector registers for use with inline
asm statements, either via the 'v' constraint or by explicit register
names (v0 ... v31).


Added:
    llvm/trunk/test/CodeGen/SystemZ/asm-19.ll
Modified:
    llvm/trunk/lib/Target/SystemZ/SystemZISelLowering.cpp
    llvm/trunk/lib/Target/SystemZ/SystemZRegisterInfo.td

Modified: llvm/trunk/lib/Target/SystemZ/SystemZISelLowering.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/SystemZ/SystemZISelLowering.cpp?rev=326609&r1=326608&r2=326609&view=diff
==============================================================================
--- llvm/trunk/lib/Target/SystemZ/SystemZISelLowering.cpp (original)
+++ llvm/trunk/lib/Target/SystemZ/SystemZISelLowering.cpp Fri Mar  2 12:36:34 2018
@@ -740,6 +740,7 @@ SystemZTargetLowering::getConstraintType
     case 'f': // Floating-point register
     case 'h': // High-part register
     case 'r': // General-purpose register
+    case 'v': // Vector register
       return C_RegisterClass;
 
     case 'Q': // Memory with base and unsigned 12-bit displacement
@@ -792,6 +793,12 @@ getSingleConstraintMatchWeight(AsmOperan
       weight = CW_Register;
     break;
 
+  case 'v': // Vector register
+    if ((type->isVectorTy() || type->isFloatingPointTy()) &&
+        Subtarget.hasVector())
+      weight = CW_Register;
+    break;
+
   case 'I': // Unsigned 8-bit constant
     if (auto *C = dyn_cast<ConstantInt>(CallOperandVal))
       if (isUInt<8>(C->getZExtValue()))
@@ -830,13 +837,13 @@ getSingleConstraintMatchWeight(AsmOperan
 // Map maps 0-based register numbers to LLVM register numbers.
 static std::pair<unsigned, const TargetRegisterClass *>
 parseRegisterNumber(StringRef Constraint, const TargetRegisterClass *RC,
-                    const unsigned *Map) {
+                    const unsigned *Map, unsigned Size) {
   assert(*(Constraint.end()-1) == '}' && "Missing '}'");
   if (isdigit(Constraint[2])) {
     unsigned Index;
     bool Failed =
         Constraint.slice(2, Constraint.size() - 1).getAsInteger(10, Index);
-    if (!Failed && Index < 16 && Map[Index])
+    if (!Failed && Index < Size && Map[Index])
       return std::make_pair(Map[Index], RC);
   }
   return std::make_pair(0U, nullptr);
@@ -873,6 +880,16 @@ SystemZTargetLowering::getRegForInlineAs
       else if (VT == MVT::f128)
         return std::make_pair(0U, &SystemZ::FP128BitRegClass);
       return std::make_pair(0U, &SystemZ::FP32BitRegClass);
+
+    case 'v': // Vector register
+      if (Subtarget.hasVector()) {
+        if (VT == MVT::f32)
+          return std::make_pair(0U, &SystemZ::VR32BitRegClass);
+        if (VT == MVT::f64)
+          return std::make_pair(0U, &SystemZ::VR64BitRegClass);
+        return std::make_pair(0U, &SystemZ::VR128BitRegClass);
+      }
+      break;
     }
   }
   if (Constraint.size() > 0 && Constraint[0] == '{') {
@@ -883,22 +900,32 @@ SystemZTargetLowering::getRegForInlineAs
     if (Constraint[1] == 'r') {
       if (VT == MVT::i32)
         return parseRegisterNumber(Constraint, &SystemZ::GR32BitRegClass,
-                                   SystemZMC::GR32Regs);
+                                   SystemZMC::GR32Regs, 16);
       if (VT == MVT::i128)
         return parseRegisterNumber(Constraint, &SystemZ::GR128BitRegClass,
-                                   SystemZMC::GR128Regs);
+                                   SystemZMC::GR128Regs, 16);
       return parseRegisterNumber(Constraint, &SystemZ::GR64BitRegClass,
-                                 SystemZMC::GR64Regs);
+                                 SystemZMC::GR64Regs, 16);
     }
     if (Constraint[1] == 'f') {
       if (VT == MVT::f32)
         return parseRegisterNumber(Constraint, &SystemZ::FP32BitRegClass,
-                                   SystemZMC::FP32Regs);
+                                   SystemZMC::FP32Regs, 16);
       if (VT == MVT::f128)
         return parseRegisterNumber(Constraint, &SystemZ::FP128BitRegClass,
-                                   SystemZMC::FP128Regs);
+                                   SystemZMC::FP128Regs, 16);
       return parseRegisterNumber(Constraint, &SystemZ::FP64BitRegClass,
-                                 SystemZMC::FP64Regs);
+                                 SystemZMC::FP64Regs, 16);
+    }
+    if (Constraint[1] == 'v') {
+      if (VT == MVT::f32)
+        return parseRegisterNumber(Constraint, &SystemZ::VR32BitRegClass,
+                                   SystemZMC::VR32Regs, 32);
+      if (VT == MVT::f64)
+        return parseRegisterNumber(Constraint, &SystemZ::VR64BitRegClass,
+                                   SystemZMC::VR64Regs, 32);
+      return parseRegisterNumber(Constraint, &SystemZ::VR128BitRegClass,
+                                 SystemZMC::VR128Regs, 32);
     }
   }
   return TargetLowering::getRegForInlineAsmConstraint(TRI, Constraint, VT);

Modified: llvm/trunk/lib/Target/SystemZ/SystemZRegisterInfo.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/SystemZ/SystemZRegisterInfo.td?rev=326609&r1=326608&r2=326609&view=diff
==============================================================================
--- llvm/trunk/lib/Target/SystemZ/SystemZRegisterInfo.td (original)
+++ llvm/trunk/lib/Target/SystemZ/SystemZRegisterInfo.td Fri Mar  2 12:36:34 2018
@@ -263,7 +263,7 @@ defm VF128 : SystemZRegClass<"VF128",
 
 // All vector registers.
 defm VR128 : SystemZRegClass<"VR128",
-                             [f128, v16i8, v8i16, v4i32, v2i64, v4f32, v2f64],
+                             [v16i8, v8i16, v4i32, v2i64, v4f32, v2f64, f128],
                              128, (add (sequence "V%u", 0, 7),
                                        (sequence "V%u", 16, 31),
                                        (sequence "V%u", 8, 15))>;

Added: llvm/trunk/test/CodeGen/SystemZ/asm-19.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/SystemZ/asm-19.ll?rev=326609&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/SystemZ/asm-19.ll (added)
+++ llvm/trunk/test/CodeGen/SystemZ/asm-19.ll Fri Mar  2 12:36:34 2018
@@ -0,0 +1,138 @@
+; Test the vector constraint "v" and explicit vector register names.
+;
+; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=z13 -no-integrated-as | FileCheck %s
+; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=z14 -no-integrated-as | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-Z14
+
+define float @f1() {
+; CHECK-LABEL: f1:
+; CHECK: lzer %f1
+; CHECK: blah %f0 %f1
+; CHECK: br %r14
+  %val = call float asm "blah $0 $1", "=&v,v" (float 0.0)
+  ret float %val
+}
+
+define double @f2() {
+; CHECK-LABEL: f2:
+; CHECK: lzdr %f1
+; CHECK: blah %f0 %f1
+; CHECK: br %r14
+  %val = call double asm "blah $0 $1", "=&v,v" (double 0.0)
+  ret double %val
+}
+
+define fp128 @f3() {
+; CHECK-LABEL: f3:
+; CHECK-Z14: vzero %v0
+; CHECK: blah %v1 %v0
+; CHECK: vst %v1, 0(%r2)
+; CHECK: br %r14
+  %val = call fp128 asm "blah $0 $1", "=&v,v" (fp128 0xL00000000000000000000000000000000)
+  ret fp128 %val
+}
+
+define <2 x i64> @f4() {
+; CHECK-LABEL: f4:
+; CHECK: vrepig  %v0, 1
+; CHECK: blah %v24 %v0
+; CHECK: br %r14
+  %val = call <2 x i64> asm "blah $0 $1", "=&v,v" (<2 x i64> <i64 1, i64 1>)
+  ret <2 x i64> %val
+}
+
+define <4 x i32> @f5() {
+; CHECK-LABEL: f5:
+; CHECK: vrepif  %v0, 1
+; CHECK: blah %v24 %v0
+; CHECK: br %r14
+  %val = call <4 x i32> asm "blah $0 $1", "=&v,v" (<4 x i32> <i32 1, i32 1, i32 1, i32 1>)
+  ret <4 x i32> %val
+}
+
+define <8 x i16> @f6() {
+; CHECK-LABEL: f6:
+; CHECK: vrepih  %v0, 1
+; CHECK: blah %v24 %v0
+; CHECK: br %r14
+  %val = call <8 x i16> asm "blah $0 $1", "=&v,v" (<8 x i16> <i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1>)
+  ret <8 x i16> %val
+}
+
+define <16 x i8> @f7() {
+; CHECK-LABEL: f7:
+; CHECK: vrepib  %v0, 1
+; CHECK: blah %v24 %v0
+; CHECK: br %r14
+  %val = call <16 x i8> asm "blah $0 $1", "=&v,v" (<16 x i8> <i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1,
+                                                              i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1>)
+  ret <16 x i8> %val
+}
+
+define <2 x double> @f8() {
+; CHECK-LABEL: f8:
+; CHECK: vgbm  %v0, 0
+; CHECK: blah %v24 %v0
+; CHECK: br %r14
+  %val = call <2 x double> asm "blah $0 $1", "=&v,v" (<2 x double> <double 0.0, double 0.0>)
+  ret <2 x double> %val
+}
+
+define <4 x float> @f9() {
+; CHECK-LABEL: f9:
+; CHECK: vgbm  %v0, 0
+; CHECK: blah %v24 %v0
+; CHECK: br %r14
+  %val = call <4 x float> asm "blah $0 $1", "=&v,v" (<4 x float> <float 0.0, float 0.0, float 0.0, float 0.0>)
+  ret <4 x float> %val
+}
+
+define float @f10() {
+; CHECK-LABEL: f10:
+; CHECK: lzer %f4
+; CHECK: blah %f4
+; CHECK: ldr %f0, %f4
+; CHECK: br %r14
+  %ret = call float asm "blah $0", "={v4},0" (float 0.0)
+  ret float %ret
+}
+
+define double @f11() {
+; CHECK-LABEL: f11:
+; CHECK: lzdr %f4
+; CHECK: blah %f4
+; CHECK: ldr %f0, %f4
+; CHECK: br %r14
+  %ret = call double asm "blah $0", "={v4},0" (double 0.0)
+  ret double %ret
+}
+
+define fp128 @f12() {
+; CHECK-LABEL: f12:
+; CHECK-Z14: vzero %v4
+; CHECK: blah %v4
+; CHECK: vst %v4, 0(%r2)
+; CHECK: br %r14
+  %ret = call fp128 asm "blah $0", "={v4},0" (fp128 0xL00000000000000000000000000000000)
+  ret fp128 %ret
+}
+
+define <2 x i64> @f13() {
+; CHECK-LABEL: f13:
+; CHECK: vrepig %v4, 1
+; CHECK: blah %v4
+; CHECK: vlr %v24, %v4
+; CHECK: br %r14
+  %ret = call <2 x i64> asm "blah $0", "={v4},0" (<2 x i64> <i64 1, i64 1>)
+  ret <2 x i64> %ret
+}
+
+define <2 x i64> @f14(<2 x i64> %in) {
+; CHECK-LABEL: f14:
+; CHECK: vlr [[REG:%v[0-9]+]], %v24
+; CHECK: blah
+; CHECK: vlr %v24, [[REG]]
+; CHECK: br %r14
+  call void asm sideeffect "blah", "~{v24},~{cc}"()
+  ret <2 x i64> %in
+}
+




More information about the llvm-commits mailing list