Index: llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp =================================================================== --- llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp +++ llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp @@ -11948,10 +11948,12 @@ SDLoc dl(N); SDValue Op(N, 0); - // Don't handle ppc_fp128 here or i1 conversions. + // Don't handle ppc_fp128 here or conversions that are out-of-range capable + // from the hardware. if (Op.getValueType() != MVT::f32 && Op.getValueType() != MVT::f64) return SDValue(); - if (Op.getOperand(0).getValueType() == MVT::i1) + if (Op.getOperand(0).getValueType().getSimpleVT() <= MVT(MVT::i1) || + Op.getOperand(0).getValueType().getSimpleVT() > MVT(MVT::i64)) return SDValue(); SDValue FirstOperand(Op.getOperand(0)); Index: llvm/trunk/test/CodeGen/PowerPC/fp-int128-fp-combine.ll =================================================================== --- llvm/trunk/test/CodeGen/PowerPC/fp-int128-fp-combine.ll +++ llvm/trunk/test/CodeGen/PowerPC/fp-int128-fp-combine.ll @@ -0,0 +1,25 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +; RUN: llc -O0 -mtriple=powerpc64le-unknown-linux-gnu < %s | FileCheck %s + +; xscvdpsxds should NOT be emitted, since it saturates the result down to i64. +define float @f_i128_f(float %v) { +; CHECK-LABEL: f_i128_f: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: mflr 0 +; CHECK-NEXT: std 0, 16(1) +; CHECK-NEXT: stdu 1, -32(1) +; CHECK-NEXT: .cfi_def_cfa_offset 32 +; CHECK-NEXT: .cfi_offset lr, 16 +; CHECK-NEXT: bl __fixsfti +; CHECK-NEXT: nop +; CHECK-NEXT: bl __floattisf +; CHECK-NEXT: nop +; CHECK-NEXT: addi 1, 1, 32 +; CHECK-NEXT: ld 0, 16(1) +; CHECK-NEXT: mtlr 0 +; CHECK-NEXT: blr +entry: + %a = fptosi float %v to i128 + %b = sitofp i128 %a to float + ret float %b +}