Index: lib/Target/PowerPC/PPCISelLowering.cpp =================================================================== --- lib/Target/PowerPC/PPCISelLowering.cpp +++ lib/Target/PowerPC/PPCISelLowering.cpp @@ -791,6 +791,8 @@ setOperationAction(ISD::FSUB, MVT::f128, Legal); setOperationAction(ISD::FDIV, MVT::f128, Legal); setOperationAction(ISD::FMUL, MVT::f128, Legal); + setOperationAction(ISD::FP_EXTEND, MVT::f128, Legal); + setLoadExtAction(ISD::EXTLOAD, MVT::f128, MVT::f64, Expand); } Index: lib/Target/PowerPC/PPCInstrVSX.td =================================================================== --- lib/Target/PowerPC/PPCInstrVSX.td +++ lib/Target/PowerPC/PPCInstrVSX.td @@ -2470,6 +2470,7 @@ // Convert DP -> QP def XSCVDPQP : X_VT5_XO5_VB5_TyVB<63, 22, 836, "xscvdpqp", vfrc, []>; + def : Pat<(f128 (fpextend f64:$src)), (f128 (XSCVDPQP $src))>; // Round & Convert QP -> DP (dword[1] is set to zero) def XSCVQPDP : X_VT5_XO5_VB5 <63, 20, 836, "xscvqpdp" , []>; Index: test/CodeGen/PowerPC/f128-arith.ll =================================================================== --- test/CodeGen/PowerPC/f128-arith.ll +++ test/CodeGen/PowerPC/f128-arith.ll @@ -131,3 +131,30 @@ ; CHECK stxv ; CHECK blr } + +; Function Attrs: norecurse nounwind +define void @dpConv2qp(double* nocapture readonly %a, fp128* nocapture %res) { +entry: + %0 = load double, double* %a, align 8 + %conv = fpext double %0 to fp128 + store fp128 %conv, fp128* %res, align 16 + ret void +; CHECK-LABEL: dpConv2qp +; CHECK-NOT: bl __extenddftf2 +; CHECK: lxsd +; CHECK: xscvdpqp +; CHECK: blr +} + +; Function Attrs: norecurse nounwind +define void @dpConv2qp_02(double %a, fp128* nocapture %res) { +entry: + %conv = fpext double %a to fp128 + store fp128 %conv, fp128* %res, align 16 + ret void +; CHECK-LABEL: dpConv2qp_02 +; CHECK-NOT: bl __extenddftf2 +; CHECK: xxlor +; CHECK: xscvdpqp +; CHECK: blr +}