Index: include/llvm/IR/IntrinsicsPowerPC.td =================================================================== --- include/llvm/IR/IntrinsicsPowerPC.td +++ include/llvm/IR/IntrinsicsPowerPC.td @@ -62,6 +62,9 @@ Intrinsic<[llvm_i64_ty], [llvm_i64_ty, llvm_i64_ty], [IntrNoMem]>; + def int_ppc_truncf128_round_to_odd + : GCCBuiltin<"__builtin_truncf128_round_to_odd">, + Intrinsic <[llvm_double_ty], [llvm_f128_ty], [IntrNoMem]>; def int_ppc_sqrtf128_round_to_odd : GCCBuiltin<"__builtin_sqrtf128_round_to_odd">, Intrinsic <[llvm_f128_ty], [llvm_f128_ty], [IntrNoMem]>; Index: lib/Target/PowerPC/PPCInstrVSX.td =================================================================== --- lib/Target/PowerPC/PPCInstrVSX.td +++ lib/Target/PowerPC/PPCInstrVSX.td @@ -2564,7 +2564,10 @@ // Round & Convert QP -> DP (dword[1] is set to zero) def XSCVQPDP : X_VT5_XO5_VB5_VSFR<63, 20, 836, "xscvqpdp" , []>; - def XSCVQPDPO : X_VT5_XO5_VB5_VSFR_Ro<63, 20, 836, "xscvqpdpo", []>; + def XSCVQPDPO : X_VT5_XO5_VB5_VSFR_Ro<63, 20, 836, "xscvqpdpo", + [(set f64:$vT, + (int_ppc_truncf128_round_to_odd + f128:$vB))]>; // Truncate & Convert QP -> (Un)Signed (D)Word (dword[1] is set to zero) def XSCVQPSDZ : X_VT5_XO5_VB5<63, 25, 836, "xscvqpsdz", []>; Index: test/CodeGen/PowerPC/builtins-ppc-p9-f128.ll =================================================================== --- test/CodeGen/PowerPC/builtins-ppc-p9-f128.ll +++ test/CodeGen/PowerPC/builtins-ppc-p9-f128.ll @@ -137,3 +137,14 @@ ; Function Attrs: nounwind readnone declare i64 @llvm.ppc.scalar.extract.expq(fp128) +define double @testTruncOdd() { +entry: + %0 = load fp128, fp128* @A, align 16 + %1 = call double @llvm.ppc.truncf128.round.to.odd(fp128 %0) + ret double %1 + ; CHECK-LABEL: testTruncOdd + ; CHECK: xscvqpdpo +} + +declare double @llvm.ppc.truncf128.round.to.odd(fp128) +