[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