Index: llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp =================================================================== --- llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp +++ llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp @@ -8073,6 +8073,14 @@ if (TestMask == fcNan) return DAG.getSetCC(DL, ResultVT, Op, Op, IsInverted ? ISD::SETO : ISD::SETUO); + if (TestMask == fcInf) { + // isinf(x) --> fabs(x) == inf + SDValue Abs = DAG.getNode(ISD::FABS, DL, OperandVT, Op); + SDValue Inf = + DAG.getConstantFP(APFloat::getInf(Semantics), DL, OperandVT); + return DAG.getSetCC(DL, ResultVT, Abs, Inf, + IsInverted ? ISD::SETONE : ISD::SETOEQ); + } } // FIXME: Placeholder until FPClassTest is marked as a BitmaskEnum. Index: llvm/test/CodeGen/PowerPC/is_fpclass.ll =================================================================== --- llvm/test/CodeGen/PowerPC/is_fpclass.ll +++ llvm/test/CodeGen/PowerPC/is_fpclass.ll @@ -123,13 +123,12 @@ define i1 @isinf_float(float %x) nounwind { ; CHECK-LABEL: isinf_float: ; CHECK: # %bb.0: -; CHECK-NEXT: xscvdpspn 0, 1 +; CHECK-NEXT: addis 3, 2, .LCPI8_0@toc@ha +; CHECK-NEXT: xsabsdp 0, 1 ; CHECK-NEXT: li 4, 1 -; CHECK-NEXT: mffprwz 3, 0 -; CHECK-NEXT: clrlwi 3, 3, 1 -; CHECK-NEXT: xoris 3, 3, 32640 -; CHECK-NEXT: cmplwi 3, 0 +; CHECK-NEXT: lfs 1, .LCPI8_0@toc@l(3) ; CHECK-NEXT: li 3, 0 +; CHECK-NEXT: fcmpu 0, 0, 1 ; CHECK-NEXT: iseleq 3, 4, 3 ; CHECK-NEXT: blr %1 = call i1 @llvm.is.fpclass.f32(float %x, i32 516) ; 0x204 = "inf" @@ -139,13 +138,12 @@ define i1 @isinf_ppc_fp128(ppc_fp128 %x) nounwind { ; CHECK-LABEL: isinf_ppc_fp128: ; CHECK: # %bb.0: -; CHECK-NEXT: mffprd 3, 1 -; CHECK-NEXT: li 4, 2047 -; CHECK-NEXT: clrldi 3, 3, 1 -; CHECK-NEXT: rldic 4, 4, 52, 1 -; CHECK-NEXT: cmpd 3, 4 -; CHECK-NEXT: li 3, 0 +; CHECK-NEXT: addis 3, 2, .LCPI9_0@toc@ha +; CHECK-NEXT: xsabsdp 0, 1 ; CHECK-NEXT: li 4, 1 +; CHECK-NEXT: lfs 1, .LCPI9_0@toc@l(3) +; CHECK-NEXT: li 3, 0 +; CHECK-NEXT: fcmpu 0, 0, 1 ; CHECK-NEXT: iseleq 3, 4, 3 ; CHECK-NEXT: blr %1 = call i1 @llvm.is.fpclass.ppcf128(ppc_fp128 %x, i32 516) ; 0x204 = "inf" @@ -155,16 +153,14 @@ define i1 @isinf_f128(fp128 %x) nounwind { ; CHECK-LABEL: isinf_f128: ; CHECK: # %bb.0: -; CHECK-NEXT: stxv 34, -16(1) -; CHECK-NEXT: li 5, 32767 -; CHECK-NEXT: ld 4, -8(1) -; CHECK-NEXT: ld 3, -16(1) -; CHECK-NEXT: rldic 5, 5, 48, 1 -; CHECK-NEXT: clrldi 4, 4, 1 -; CHECK-NEXT: xor 4, 4, 5 -; CHECK-NEXT: or 3, 3, 4 -; CHECK-NEXT: cntlzd 3, 3 -; CHECK-NEXT: rldicl 3, 3, 58, 63 +; CHECK-NEXT: addis 3, 2, .LCPI10_0@toc@ha +; CHECK-NEXT: xsabsqp 2, 2 +; CHECK-NEXT: li 4, 1 +; CHECK-NEXT: addi 3, 3, .LCPI10_0@toc@l +; CHECK-NEXT: lxv 35, 0(3) +; CHECK-NEXT: li 3, 0 +; CHECK-NEXT: xscmpuqp 0, 2, 3 +; CHECK-NEXT: iseleq 3, 4, 3 ; CHECK-NEXT: blr %1 = call i1 @llvm.is.fpclass.f128(fp128 %x, i32 516) ; 0x204 = "inf" ret i1 %1 Index: llvm/test/CodeGen/X86/is_fpclass-fp80.ll =================================================================== --- llvm/test/CodeGen/X86/is_fpclass-fp80.ll +++ llvm/test/CodeGen/X86/is_fpclass-fp80.ll @@ -253,25 +253,26 @@ define i1 @is_inf_f80(x86_fp80 %x) { ; CHECK-32-LABEL: is_inf_f80: ; CHECK-32: # %bb.0: # %entry -; CHECK-32-NEXT: movl {{[0-9]+}}(%esp), %eax -; CHECK-32-NEXT: notl %eax -; CHECK-32-NEXT: movl $-2147483648, %ecx # imm = 0x80000000 -; CHECK-32-NEXT: xorl {{[0-9]+}}(%esp), %ecx -; CHECK-32-NEXT: andl $32767, %eax # imm = 0x7FFF -; CHECK-32-NEXT: orl {{[0-9]+}}(%esp), %eax -; CHECK-32-NEXT: orl %ecx, %eax -; CHECK-32-NEXT: sete %al +; CHECK-32-NEXT: fldt {{[0-9]+}}(%esp) +; CHECK-32-NEXT: fabs +; CHECK-32-NEXT: flds {{\.?LCPI[0-9]+_[0-9]+}} +; CHECK-32-NEXT: fxch %st(1) +; CHECK-32-NEXT: fucompp +; CHECK-32-NEXT: fnstsw %ax +; CHECK-32-NEXT: # kill: def $ah killed $ah killed $ax +; CHECK-32-NEXT: sahf +; CHECK-32-NEXT: setae %al ; CHECK-32-NEXT: retl ; ; CHECK-64-LABEL: is_inf_f80: ; CHECK-64: # %bb.0: # %entry -; CHECK-64-NEXT: movl {{[0-9]+}}(%rsp), %eax -; CHECK-64-NEXT: notl %eax -; CHECK-64-NEXT: andl $32767, %eax # imm = 0x7FFF -; CHECK-64-NEXT: movabsq $-9223372036854775808, %rcx # imm = 0x8000000000000000 -; CHECK-64-NEXT: xorq {{[0-9]+}}(%rsp), %rcx -; CHECK-64-NEXT: orq %rax, %rcx -; CHECK-64-NEXT: sete %al +; CHECK-64-NEXT: fldt {{[0-9]+}}(%rsp) +; CHECK-64-NEXT: fabs +; CHECK-64-NEXT: flds {{\.?LCPI[0-9]+_[0-9]+}}(%rip) +; CHECK-64-NEXT: fxch %st(1) +; CHECK-64-NEXT: fucompi %st(1), %st +; CHECK-64-NEXT: fstp %st(0) +; CHECK-64-NEXT: setae %al ; CHECK-64-NEXT: retq entry: %0 = tail call i1 @llvm.is.fpclass.f80(x86_fp80 %x, i32 516) ; 0x204 = "inf" Index: llvm/test/CodeGen/X86/is_fpclass.ll =================================================================== --- llvm/test/CodeGen/X86/is_fpclass.ll +++ llvm/test/CodeGen/X86/is_fpclass.ll @@ -143,18 +143,22 @@ define i1 @isinf_f(float %x) { ; CHECK-32-LABEL: isinf_f: ; CHECK-32: # %bb.0: # %entry -; CHECK-32-NEXT: movl $2147483647, %eax # imm = 0x7FFFFFFF -; CHECK-32-NEXT: andl {{[0-9]+}}(%esp), %eax -; CHECK-32-NEXT: cmpl $2139095040, %eax # imm = 0x7F800000 -; CHECK-32-NEXT: sete %al +; CHECK-32-NEXT: flds {{[0-9]+}}(%esp) +; CHECK-32-NEXT: fabs +; CHECK-32-NEXT: flds {{\.?LCPI[0-9]+_[0-9]+}} +; CHECK-32-NEXT: fxch %st(1) +; CHECK-32-NEXT: fucompp +; CHECK-32-NEXT: fnstsw %ax +; CHECK-32-NEXT: # kill: def $ah killed $ah killed $ax +; CHECK-32-NEXT: sahf +; CHECK-32-NEXT: setae %al ; CHECK-32-NEXT: retl ; ; CHECK-64-LABEL: isinf_f: ; CHECK-64: # %bb.0: # %entry -; CHECK-64-NEXT: movd %xmm0, %eax -; CHECK-64-NEXT: andl $2147483647, %eax # imm = 0x7FFFFFFF -; CHECK-64-NEXT: cmpl $2139095040, %eax # imm = 0x7F800000 -; CHECK-64-NEXT: sete %al +; CHECK-64-NEXT: andps {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0 +; CHECK-64-NEXT: ucomiss {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0 +; CHECK-64-NEXT: setae %al ; CHECK-64-NEXT: retq entry: %0 = tail call i1 @llvm.is.fpclass.f32(float %x, i32 516) ; 0x204 = "inf" @@ -164,17 +168,21 @@ define i1 @not_isinf_f(float %x) { ; CHECK-32-LABEL: not_isinf_f: ; CHECK-32: # %bb.0: # %entry -; CHECK-32-NEXT: movl $2147483647, %eax # imm = 0x7FFFFFFF -; CHECK-32-NEXT: andl {{[0-9]+}}(%esp), %eax -; CHECK-32-NEXT: cmpl $2139095040, %eax # imm = 0x7F800000 +; CHECK-32-NEXT: flds {{[0-9]+}}(%esp) +; CHECK-32-NEXT: fabs +; CHECK-32-NEXT: flds {{\.?LCPI[0-9]+_[0-9]+}} +; CHECK-32-NEXT: fxch %st(1) +; CHECK-32-NEXT: fucompp +; CHECK-32-NEXT: fnstsw %ax +; CHECK-32-NEXT: # kill: def $ah killed $ah killed $ax +; CHECK-32-NEXT: sahf ; CHECK-32-NEXT: setne %al ; CHECK-32-NEXT: retl ; ; CHECK-64-LABEL: not_isinf_f: ; CHECK-64: # %bb.0: # %entry -; CHECK-64-NEXT: movd %xmm0, %eax -; CHECK-64-NEXT: andl $2147483647, %eax # imm = 0x7FFFFFFF -; CHECK-64-NEXT: cmpl $2139095040, %eax # imm = 0x7F800000 +; CHECK-64-NEXT: andps {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0 +; CHECK-64-NEXT: ucomiss {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0 ; CHECK-64-NEXT: setne %al ; CHECK-64-NEXT: retq entry: @@ -1149,21 +1157,22 @@ define i1 @isinf_d(double %x) { ; CHECK-32-LABEL: isinf_d: ; CHECK-32: # %bb.0: # %entry -; CHECK-32-NEXT: movl $2147483647, %eax # imm = 0x7FFFFFFF -; CHECK-32-NEXT: andl {{[0-9]+}}(%esp), %eax -; CHECK-32-NEXT: xorl $2146435072, %eax # imm = 0x7FF00000 -; CHECK-32-NEXT: orl {{[0-9]+}}(%esp), %eax -; CHECK-32-NEXT: sete %al +; CHECK-32-NEXT: fldl {{[0-9]+}}(%esp) +; CHECK-32-NEXT: fabs +; CHECK-32-NEXT: flds {{\.?LCPI[0-9]+_[0-9]+}} +; CHECK-32-NEXT: fxch %st(1) +; CHECK-32-NEXT: fucompp +; CHECK-32-NEXT: fnstsw %ax +; CHECK-32-NEXT: # kill: def $ah killed $ah killed $ax +; CHECK-32-NEXT: sahf +; CHECK-32-NEXT: setae %al ; CHECK-32-NEXT: retl ; ; CHECK-64-LABEL: isinf_d: ; CHECK-64: # %bb.0: # %entry -; CHECK-64-NEXT: movq %xmm0, %rax -; CHECK-64-NEXT: movabsq $9223372036854775807, %rcx # imm = 0x7FFFFFFFFFFFFFFF -; CHECK-64-NEXT: andq %rax, %rcx -; CHECK-64-NEXT: movabsq $9218868437227405312, %rax # imm = 0x7FF0000000000000 -; CHECK-64-NEXT: cmpq %rax, %rcx -; CHECK-64-NEXT: sete %al +; CHECK-64-NEXT: andpd {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0 +; CHECK-64-NEXT: ucomisd {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0 +; CHECK-64-NEXT: setae %al ; CHECK-64-NEXT: retq entry: %0 = tail call i1 @llvm.is.fpclass.f64(double %x, i32 516) ; 0x204 = "inf"