diff options
author | Fangrui Song <maskray@google.com> | 2019-07-04 04:44:42 +0000 |
---|---|---|
committer | Fangrui Song <maskray@google.com> | 2019-07-04 04:44:42 +0000 |
commit | 1f333562de96bb9343721a703dee1277929d61e4 (patch) | |
tree | e793533d10f87f6b8783b0ec2acbcc2c76d4f131 | |
parent | fa9d232e4389bbd9ca82f8b6b34a1784107835fc (diff) | |
download | bcm5719-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.h | 3 | ||||
-rw-r--r-- | clang/test/CodeGen/ppc64-inline-asm.c | 13 | ||||
-rw-r--r-- | llvm/lib/Target/PowerPC/PPCISelLowering.cpp | 10 | ||||
-rw-r--r-- | llvm/test/CodeGen/PowerPC/inlineasm-vsx-reg.ll | 9 | ||||
-rw-r--r-- | llvm/test/CodeGen/PowerPC/vec-asm-disabled.ll | 12 |
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" } |