diff --git a/clang/lib/Basic/Targets/PPC.h b/clang/lib/Basic/Targets/PPC.h --- a/clang/lib/Basic/Targets/PPC.h +++ b/clang/lib/Basic/Targets/PPC.h @@ -207,7 +207,8 @@ 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 --- a/clang/test/CodeGen/ppc64-inline-asm.c +++ b/clang/test/CodeGen/ppc64-inline-asm.c @@ -24,3 +24,16 @@ // 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 --- a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp +++ b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp @@ -13958,7 +13958,7 @@ 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); @@ -13986,10 +13986,12 @@ 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: @@ -14075,7 +14077,7 @@ 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 --- a/llvm/test/CodeGen/PowerPC/inlineasm-vsx-reg.ll +++ b/llvm/test/CodeGen/PowerPC/inlineasm-vsx-reg.ll @@ -38,3 +38,12 @@ ; 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 --- a/llvm/test/CodeGen/PowerPC/vec-asm-disabled.ll +++ b/llvm/test/CodeGen/PowerPC/vec-asm-disabled.ll @@ -19,5 +19,17 @@ ; 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" }