summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFangrui Song <maskray@google.com>2019-07-04 04:44:42 +0000
committerFangrui Song <maskray@google.com>2019-07-04 04:44:42 +0000
commit1f333562de96bb9343721a703dee1277929d61e4 (patch)
treee793533d10f87f6b8783b0ec2acbcc2c76d4f131
parentfa9d232e4389bbd9ca82f8b6b34a1784107835fc (diff)
downloadbcm5719-llvm-1f333562de96bb9343721a703dee1277929d61e4.tar.gz
bcm5719-llvm-1f333562de96bb9343721a703dee1277929d61e4.zip
[PowerPC] Support constraint code "ww"
Summary: "ww" and "ws" are both constraint codes for VSX vector registers that hold scalar double data. "ww" is preferred for float while "ws" is preferred for double. Reviewed By: jsji Differential Revision: https://reviews.llvm.org/D64119 llvm-svn: 365106
-rw-r--r--clang/lib/Basic/Targets/PPC.h3
-rw-r--r--clang/test/CodeGen/ppc64-inline-asm.c13
-rw-r--r--llvm/lib/Target/PowerPC/PPCISelLowering.cpp10
-rw-r--r--llvm/test/CodeGen/PowerPC/inlineasm-vsx-reg.ll9
-rw-r--r--llvm/test/CodeGen/PowerPC/vec-asm-disabled.ll12
5 files changed, 42 insertions, 5 deletions
diff --git a/clang/lib/Basic/Targets/PPC.h b/clang/lib/Basic/Targets/PPC.h
index 465a7cf4221..6c132e3841f 100644
--- a/clang/lib/Basic/Targets/PPC.h
+++ b/clang/lib/Basic/Targets/PPC.h
@@ -207,7 +207,8 @@ public:
switch (Name[1]) {
case 'd': // VSX vector register to hold vector double data
case 'f': // VSX vector register to hold vector float data
- case 's': // VSX vector register to hold scalar float data
+ case 's': // VSX vector register to hold scalar double data
+ case 'w': // VSX vector register to hold scalar double data
case 'a': // Any VSX register
case 'c': // An individual CR bit
case 'i': // FP or VSX register to hold 64-bit integers data
diff --git a/clang/test/CodeGen/ppc64-inline-asm.c b/clang/test/CodeGen/ppc64-inline-asm.c
index 552fe280e00..3e958c328f9 100644
--- a/clang/test/CodeGen/ppc64-inline-asm.c
+++ b/clang/test/CodeGen/ppc64-inline-asm.c
@@ -24,3 +24,16 @@ unsigned char test_wc_i8(unsigned char b1, unsigned char b2) {
// CHECK: call i8 asm "crand $0, $1, $2", "=^wc,^wc,^wc"(i8 %b1, i8 %b2)
}
+float test_fmaxf(float x, float y) {
+ asm("xsmaxdp %x0, %x1, %x2" : "=ww"(x) : "ww"(x), "ww"(y));
+ return x;
+// CHECK-LABEL: float @test_fmaxf(float %x, float %y)
+// CHECK: call float asm "xsmaxdp ${0:x}, ${1:x}, ${2:x}", "=^ww,^ww,^ww"(float %x, float %y)
+}
+
+double test_fmax(double x, double y) {
+ asm("xsmaxdp %x0, %x1, %x2" : "=ws"(x) : "ws"(x), "ws"(y));
+ return x;
+// CHECK-LABEL: double @test_fmax(double %x, double %y)
+// CHECK: call double asm "xsmaxdp ${0:x}, ${1:x}, ${2:x}", "=^ws,^ws,^ws"(double %x, double %y)
+}
diff --git a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
index aad7ef6ef68..6252faf4be6 100644
--- a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
+++ b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
@@ -13962,7 +13962,7 @@ PPCTargetLowering::getConstraintType(StringRef Constraint) const {
return C_RegisterClass;
} else if (Constraint == "wa" || Constraint == "wd" ||
Constraint == "wf" || Constraint == "ws" ||
- Constraint == "wi") {
+ Constraint == "wi" || Constraint == "ww") {
return C_RegisterClass; // VSX registers.
}
return TargetLowering::getConstraintType(Constraint);
@@ -13990,10 +13990,12 @@ PPCTargetLowering::getSingleConstraintMatchWeight(
StringRef(constraint) == "wf") &&
type->isVectorTy())
return CW_Register;
- else if (StringRef(constraint) == "ws" && type->isDoubleTy())
- return CW_Register;
else if (StringRef(constraint) == "wi" && type->isIntegerTy(64))
return CW_Register; // just hold 64-bit integers data.
+ else if (StringRef(constraint) == "ws" && type->isDoubleTy())
+ return CW_Register;
+ else if (StringRef(constraint) == "ww" && type->isFloatTy())
+ return CW_Register;
switch (*constraint) {
default:
@@ -14079,7 +14081,7 @@ PPCTargetLowering::getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI,
Constraint == "wf" || Constraint == "wi") &&
Subtarget.hasVSX()) {
return std::make_pair(0U, &PPC::VSRCRegClass);
- } else if (Constraint == "ws" && Subtarget.hasVSX()) {
+ } else if ((Constraint == "ws" || Constraint == "ww") && Subtarget.hasVSX()) {
if (VT == MVT::f32 && Subtarget.hasP8Vector())
return std::make_pair(0U, &PPC::VSSRCRegClass);
else
diff --git a/llvm/test/CodeGen/PowerPC/inlineasm-vsx-reg.ll b/llvm/test/CodeGen/PowerPC/inlineasm-vsx-reg.ll
index b3cbefa2dbd..088dda575c5 100644
--- a/llvm/test/CodeGen/PowerPC/inlineasm-vsx-reg.ll
+++ b/llvm/test/CodeGen/PowerPC/inlineasm-vsx-reg.ll
@@ -38,3 +38,12 @@ define double @test() {
; CHECK: mtvsrd v2, r1
; CHECK: #NO_APP
}
+
+define float @test_ww(float %x, float %y) {
+ %1 = tail call float asm "xsmaxdp ${0:x}, ${1:x}, ${2:x}", "=^ww,^ww,^ww"(float %x, float %y)
+ ret float %1
+; CHECK-LABEL: test_ww:
+; CHECK: #APP
+; CHECK: xsmaxdp f1, f1, f2
+; CHECK: #NO_APP
+}
diff --git a/llvm/test/CodeGen/PowerPC/vec-asm-disabled.ll b/llvm/test/CodeGen/PowerPC/vec-asm-disabled.ll
index 614f3e3f03a..573abab9dcf 100644
--- a/llvm/test/CodeGen/PowerPC/vec-asm-disabled.ll
+++ b/llvm/test/CodeGen/PowerPC/vec-asm-disabled.ll
@@ -19,5 +19,17 @@ entry:
; CHECK: error: couldn't allocate output register for constraint 'wi'
}
+define float @test_ww(float %x, float %y) #0 {
+ %1 = tail call float asm "xsmaxdp ${0:x},${1:x},${2:x}", "=^ww,^ww,^ww"(float %x, float %y) #0
+ ret float %1
+; CHECK: error: couldn't allocate output register for constraint 'ww'
+}
+
+define double @test_ws(double %x, double %y) #0 {
+ %1 = tail call double asm "xsmaxdp ${0:x},${1:x},${2:x}", "=^ws,^ws,^ws"(double %x, double %y) #0
+ ret double %1
+; CHECK: error: couldn't allocate output register for constraint 'ws'
+}
+
attributes #0 = { nounwind "target-features"="-vsx" }
OpenPOWER on IntegriCloud