Index: lib/Target/PowerPC/PPCISelDAGToDAG.cpp =================================================================== --- lib/Target/PowerPC/PPCISelDAGToDAG.cpp +++ lib/Target/PowerPC/PPCISelDAGToDAG.cpp @@ -3518,7 +3518,6 @@ case ISD::SETGE: return PPC::PRED_GE; case ISD::SETO: return PPC::PRED_NU; case ISD::SETUO: return PPC::PRED_UN; - // These two are invalid for floating point. Assume we have int. case ISD::SETULT: return PPC::PRED_LT; case ISD::SETUGT: return PPC::PRED_GT; } Index: lib/Target/PowerPC/PPCISelLowering.cpp =================================================================== --- lib/Target/PowerPC/PPCISelLowering.cpp +++ lib/Target/PowerPC/PPCISelLowering.cpp @@ -442,10 +442,10 @@ setOperationAction(ISD::INTRINSIC_VOID, MVT::Other, Custom); // Comparisons that require checking two conditions. - setCondCodeAction(ISD::SETULT, MVT::f32, Expand); - setCondCodeAction(ISD::SETULT, MVT::f64, Expand); - setCondCodeAction(ISD::SETUGT, MVT::f32, Expand); - setCondCodeAction(ISD::SETUGT, MVT::f64, Expand); + setCondCodeAction(ISD::SETULT, MVT::f32, Legal); + setCondCodeAction(ISD::SETULT, MVT::f64, Legal); + setCondCodeAction(ISD::SETUGT, MVT::f32, Legal); + setCondCodeAction(ISD::SETUGT, MVT::f64, Legal); setCondCodeAction(ISD::SETUEQ, MVT::f32, Expand); setCondCodeAction(ISD::SETUEQ, MVT::f64, Expand); setCondCodeAction(ISD::SETOGE, MVT::f32, Expand); Index: lib/Target/PowerPC/PPCInstrInfo.td =================================================================== --- lib/Target/PowerPC/PPCInstrInfo.td +++ lib/Target/PowerPC/PPCInstrInfo.td @@ -3202,8 +3202,7 @@ (CRXOR $s1, $s2)>; // match setcc on non-i1 (non-vector) variables. Note that SETUEQ, SETOGE, -// SETOLE, SETONE, SETULT and SETUGT should be expanded by legalize for -// floating-point types. +// SETOLE, SETONE, should be expanded by legalize for floating-point types. multiclass CRNotPat { def : Pat; @@ -3532,6 +3531,12 @@ (EXTRACT_SUBREG (FCMPUS $s1, $s2), sub_eq)>; def : Pat<(i1 (setcc f32:$s1, f32:$s2, SETUO)), (EXTRACT_SUBREG (FCMPUS $s1, $s2), sub_un)>; +def : Pat<(i1 (setcc f32:$s1, f32:$s2, SETULT)), + (CROR (EXTRACT_SUBREG (FCMPUS $s1, $s2), sub_lt), + (EXTRACT_SUBREG (FCMPUS $s1, $s2), sub_un))>; +def : Pat<(i1 (setcc f32:$s1, f32:$s2, SETUGT)), + (CROR (EXTRACT_SUBREG (FCMPUS $s1, $s2), sub_gt), + (EXTRACT_SUBREG (FCMPUS $s1, $s2), sub_un))>; defm : CRNotPat<(i1 (setcc f32:$s1, f32:$s2, SETUGE)), (EXTRACT_SUBREG (FCMPUS $s1, $s2), sub_lt)>; @@ -3563,6 +3568,12 @@ (EXTRACT_SUBREG (FCMPUD $s1, $s2), sub_eq)>; def : Pat<(i1 (setcc f64:$s1, f64:$s2, SETUO)), (EXTRACT_SUBREG (FCMPUD $s1, $s2), sub_un)>; +def : Pat<(i1 (setcc f64:$s1, f64:$s2, SETULT)), + (CROR (EXTRACT_SUBREG (FCMPUD $s1, $s2), sub_lt), + (EXTRACT_SUBREG (FCMPUD $s1, $s2), sub_un))>; +def : Pat<(i1 (setcc f64:$s1, f64:$s2, SETUGT)), + (CROR (EXTRACT_SUBREG (FCMPUD $s1, $s2), sub_gt), + (EXTRACT_SUBREG (FCMPUD $s1, $s2), sub_un))>; defm : CRNotPat<(i1 (setcc f64:$s1, f64:$s2, SETUGE)), (EXTRACT_SUBREG (FCMPUD $s1, $s2), sub_lt)>; Index: test/CodeGen/PowerPC/test_fp_ugt.ll =================================================================== --- /dev/null +++ test/CodeGen/PowerPC/test_fp_ugt.ll @@ -0,0 +1,43 @@ +; RUN: llc < %s -mcpu=pwr8 -mtriple=powerpc64le-unknown-unknown -O3 -ppc-asm-full-reg-names -verify-machineinstrs | FileCheck %s --check-prefix=CHECK + +define i64 @test_fp_ugt(ppc_fp128 %a) { +entry: + %0 = fcmp olt ppc_fp128 %a, 0xM00000000000000000000000000000000 + br i1 %0, label %bb5, label %bb1 + +bb1: + %1 = fmul ppc_fp128 %a, 0xM3DF00000000000000000000000000000 + %2 = fptoui ppc_fp128 %1 to i32 + %3 = zext i32 %2 to i64 + %4 = shl i64 %3, 32 + %5 = uitofp i64 %4 to ppc_fp128 + %6 = fsub ppc_fp128 %a, %5 + %7 = fcmp olt ppc_fp128 %6, 0xM00000000000000000000000000000000 + br i1 %7, label %bb2, label %bb3 + +bb2: + %8 = fsub ppc_fp128 0xM80000000000000000000000000000000, %6 + %9 = fptoui ppc_fp128 %8 to i32 + %10 = zext i32 %9 to i64 + %11 = sub i64 %4, %10 + ret i64 %11 + +bb3: + %12 = fptoui ppc_fp128 %6 to i32 + %13 = zext i32 %12 to i64 + %14 = or i64 %13, %4 + ret i64 %14 + +bb5: + ret i64 0 + +;CHECK-LABEL: test_fp_ugt +;CHECK: fmr f29, f1 +;CHECK-NEXT: fmr f28, f2 +;CHECK-NEXT: fcmpu cr0, f29, f31 +;CHECK-NEXT: fcmpu cr2, f28, f31 +;CHECK-NEXT: crandc 4*cr5+lt, eq, 4*cr2+lt +;CHECK-NEXT: cror 4*cr5+gt, gt, un +;CHECK-NEXT: cror 4*cr5+lt, 4*cr5+gt, 4*cr5+lt +;CHECK-NEXT: bc 12, 4*cr5+lt, .LBB +} Index: test/CodeGen/PowerPC/test_fp_ugt0.ll =================================================================== --- /dev/null +++ test/CodeGen/PowerPC/test_fp_ugt0.ll @@ -0,0 +1,22 @@ +; RUN: llc < %s -mcpu=pwr8 -mattr=-vsx -mtriple=powerpc64le-unknown-unknown -O3 -ppc-asm-full-reg-names -verify-machineinstrs | FileCheck %s --check-prefix=CHECK +define i1 @test_fp_ugt_0(double %t0) { +; CHECK-LABEL: test_fp_ugt_0: +; CHECK: lfs f0, 0(r3) +; CHECK: fcmpu cr0, f1, f0 +; CHECK: ble cr0, .LBB0_2 +; CHECK: # %bb.1: # %good +; CHECK: li r3, 1 +; CHECK: blr +; CHECK: .LBB0_2: # %bad +; CHECK: li r3, 0 +; CHECK: blr +entry: + %t1 = fcmp ugt double %t0, 0.000000e+00 + br i1 %t1, label %good, label %bad + +bad: + ret i1 false + +good: + ret i1 true +} Index: test/CodeGen/PowerPC/test_fp_ult.ll =================================================================== --- /dev/null +++ test/CodeGen/PowerPC/test_fp_ult.ll @@ -0,0 +1,43 @@ +; RUN: llc < %s -mcpu=pwr8 -mtriple=powerpc64le-unknown-unknown -O3 -ppc-asm-full-reg-names -verify-machineinstrs | FileCheck %s --check-prefix=CHECK + +define i64 @test_fp_ult(ppc_fp128 %a) { +entry: + %0 = fcmp ogt ppc_fp128 %a, 0xM00000000000000000000000000000000 + br i1 %0, label %bb5, label %bb1 + +bb1: + %1 = fmul ppc_fp128 %a, 0xM3DF00000000000000000000000000000 + %2 = fptoui ppc_fp128 %1 to i32 + %3 = zext i32 %2 to i64 + %4 = shl i64 %3, 32 + %5 = uitofp i64 %4 to ppc_fp128 + %6 = fsub ppc_fp128 %a, %5 + %7 = fcmp ogt ppc_fp128 %6, 0xM00000000000000000000000000000000 + br i1 %7, label %bb2, label %bb3 + +bb2: + %8 = fsub ppc_fp128 0xM80000000000000000000000000000000, %6 + %9 = fptoui ppc_fp128 %8 to i32 + %10 = zext i32 %9 to i64 + %11 = sub i64 %4, %10 + ret i64 %11 + +bb3: + %12 = fptoui ppc_fp128 %6 to i32 + %13 = zext i32 %12 to i64 + %14 = or i64 %13, %4 + ret i64 %14 + +bb5: + ret i64 0 + +;CHECK-LABEL: test_fp_ult +;CHECK: fmr f29, f1 +;CHECK-NEXT: fmr f28, f2 +;CHECK-NEXT: fcmpu cr0, f29, f31 +;CHECK-NEXT: fcmpu cr2, f28, f31 +;CHECK-NEXT: crandc 4*cr5+lt, eq, 4*cr2+gt +;CHECK-NEXT: cror 4*cr5+gt, lt, un +;CHECK-NEXT: cror 4*cr5+lt, 4*cr5+gt, 4*cr5+lt +;CHECK-NEXT: bc 12, 4*cr5+lt, .LBB +} Index: test/CodeGen/PowerPC/test_fp_ult0.ll =================================================================== --- /dev/null +++ test/CodeGen/PowerPC/test_fp_ult0.ll @@ -0,0 +1,22 @@ +; RUN: llc < %s -mcpu=pwr8 -mattr=-vsx -mtriple=powerpc64le-unknown-unknown -O3 -ppc-asm-full-reg-names -verify-machineinstrs | FileCheck %s --check-prefix=CHECK +define i1 @test_fp_ult_0(double %t0) { +; CHECK-LABEL: test_fp_ult_0: +; CHECK: lfs f0, 0(r3) +; CHECK: fcmpu cr0, f1, f0 +; CHECK: bge cr0, .LBB0_2 +; CHECK: # %bb.1: # %good +; CHECK: li r3, 1 +; CHECK: blr +; CHECK: .LBB0_2: # %bad +; CHECK: li r3, 0 +; CHECK: blr +entry: + %t1 = fcmp ult double %t0, 0.000000e+00 + br i1 %t1, label %good, label %bad + +bad: + ret i1 false + +good: + ret i1 true +}