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 @@ -15648,7 +15648,13 @@ } else if ((Constraint == "wa" || Constraint == "wd" || Constraint == "wf" || Constraint == "wi") && Subtarget.hasVSX()) { - return std::make_pair(0U, &PPC::VSRCRegClass); + // A VSX register for either a scalar (FP) or vector. There is no + // support for single precision scalars on subtargets prior to Power8. + if (VT.isVector()) + return std::make_pair(0U, &PPC::VSRCRegClass); + if (VT == MVT::f32 && Subtarget.hasP8Vector()) + return std::make_pair(0U, &PPC::VSSRCRegClass); + return std::make_pair(0U, &PPC::VSFRCRegClass); } else if ((Constraint == "ws" || Constraint == "ww") && Subtarget.hasVSX()) { if (VT == MVT::f32 && Subtarget.hasP8Vector()) return std::make_pair(0U, &PPC::VSSRCRegClass); diff --git a/llvm/test/CodeGen/PowerPC/wa-asm-fpr.ll b/llvm/test/CodeGen/PowerPC/wa-asm-fpr.ll new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/PowerPC/wa-asm-fpr.ll @@ -0,0 +1,22 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +; RUN: llc -mtriple powerpc64le-linux-gnu --ppc-asm-full-reg-names \ +; RUN: -verify-machineinstrs -mattr=vsx -mattr=altivec < %s | \ +; RUN: FileCheck %s + +define double @foo(<2 x double> %a) { +; CHECK-LABEL: foo: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: #APP +; CHECK-NEXT: xvabsdp vs0, vs34 +; CHECK-NEXT: xxsldwi vs1, vs0, vs0, 2 +; CHECK-EMPTY: +; CHECK-NEXT: #NO_APP +; CHECK-NEXT: xsadddp f1, f0, f1 +; CHECK-NEXT: blr +entry: + %0 = call { double, double } asm "xvabsdp ${0:x}, ${2:x} \0Axxsldwi ${1:x}, ${0:x}, ${0:x}, 2 \0A", "=^wa,=^wa,^wa,0"(<2 x double> %a, double undef) + %asmresult = extractvalue { double, double } %0, 0 + %asmresult1 = extractvalue { double, double } %0, 1 + %add = fadd double %asmresult, %asmresult1 + ret double %add +}