Index: llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp =================================================================== --- llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp +++ llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp @@ -8081,6 +8081,15 @@ return DAG.getSetCC(DL, ResultVT, Abs, Inf, IsInverted ? ISD::SETONE : ISD::SETOEQ); } + + if (TestMask == fcPosInf || TestMask == fcNegInf) { + // isposinf(x) --> x == inf + // isneginf(x) --> x == -inf + SDValue Inf = DAG.getConstantFP( + APFloat::getInf(Semantics, TestMask == fcNegInf), DL, OperandVT); + return DAG.getSetCC(DL, ResultVT, Op, Inf, + IsInverted ? ISD::SETONE : ISD::SETOEQ); + } } // FIXME: Placeholder until FPClassTest is marked as a BitmaskEnum. 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 @@ -282,23 +282,24 @@ define i1 @is_posinf_f80(x86_fp80 %x) { ; CHECK-32-LABEL: is_posinf_f80: ; CHECK-32: # %bb.0: # %entry -; CHECK-32-NEXT: movzwl {{[0-9]+}}(%esp), %eax -; CHECK-32-NEXT: movl $-2147483648, %ecx # imm = 0x80000000 -; CHECK-32-NEXT: xorl {{[0-9]+}}(%esp), %ecx -; CHECK-32-NEXT: xorl $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: 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_posinf_f80: ; CHECK-64: # %bb.0: # %entry -; CHECK-64-NEXT: movzwl {{[0-9]+}}(%rsp), %eax -; CHECK-64-NEXT: movabsq $-9223372036854775808, %rcx # imm = 0x8000000000000000 -; CHECK-64-NEXT: xorq {{[0-9]+}}(%rsp), %rcx -; CHECK-64-NEXT: xorq $32767, %rax # imm = 0x7FFF -; CHECK-64-NEXT: orq %rcx, %rax -; CHECK-64-NEXT: sete %al +; CHECK-64-NEXT: fldt {{[0-9]+}}(%rsp) +; 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 512) ; 0x200 = "+inf" @@ -308,24 +309,22 @@ define i1 @is_neginf_f80(x86_fp80 %x) { ; CHECK-32-LABEL: is_neginf_f80: ; CHECK-32: # %bb.0: # %entry -; CHECK-32-NEXT: movzwl {{[0-9]+}}(%esp), %eax -; CHECK-32-NEXT: xorl $65535, %eax # imm = 0xFFFF -; CHECK-32-NEXT: movl $-2147483648, %ecx # imm = 0x80000000 -; CHECK-32-NEXT: xorl {{[0-9]+}}(%esp), %ecx -; 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: flds {{\.?LCPI[0-9]+_[0-9]+}} +; 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_neginf_f80: ; CHECK-64: # %bb.0: # %entry -; CHECK-64-NEXT: movl {{[0-9]+}}(%rsp), %eax -; CHECK-64-NEXT: notl %eax -; CHECK-64-NEXT: movzwl %ax, %eax -; 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: flds {{\.?LCPI[0-9]+_[0-9]+}}(%rip) +; 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 4) ; "-inf" Index: llvm/test/CodeGen/X86/is_fpclass.ll =================================================================== --- llvm/test/CodeGen/X86/is_fpclass.ll +++ llvm/test/CodeGen/X86/is_fpclass.ll @@ -193,15 +193,20 @@ define i1 @is_plus_inf_f(float %x) { ; CHECK-32-LABEL: is_plus_inf_f: ; CHECK-32: # %bb.0: # %entry -; CHECK-32-NEXT: cmpl $2139095040, {{[0-9]+}}(%esp) # imm = 0x7F800000 -; CHECK-32-NEXT: sete %al +; CHECK-32-NEXT: flds {{[0-9]+}}(%esp) +; 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_plus_inf_f: ; CHECK-64: # %bb.0: # %entry -; CHECK-64-NEXT: movd %xmm0, %eax -; CHECK-64-NEXT: cmpl $2139095040, %eax # imm = 0x7F800000 -; CHECK-64-NEXT: sete %al +; 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 512) ; 0x200 = "+inf" @@ -211,15 +216,20 @@ define i1 @is_minus_inf_f(float %x) { ; CHECK-32-LABEL: is_minus_inf_f: ; CHECK-32: # %bb.0: # %entry -; CHECK-32-NEXT: cmpl $-8388608, {{[0-9]+}}(%esp) # imm = 0xFF800000 -; CHECK-32-NEXT: sete %al +; CHECK-32-NEXT: flds {{[0-9]+}}(%esp) +; CHECK-32-NEXT: flds {{\.?LCPI[0-9]+_[0-9]+}} +; 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_minus_inf_f: ; CHECK-64: # %bb.0: # %entry -; CHECK-64-NEXT: movd %xmm0, %eax -; CHECK-64-NEXT: cmpl $-8388608, %eax # imm = 0xFF800000 -; CHECK-64-NEXT: sete %al +; CHECK-64-NEXT: movss {{.*#+}} xmm1 = mem[0],zero,zero,zero +; CHECK-64-NEXT: ucomiss %xmm0, %xmm1 +; CHECK-64-NEXT: setae %al ; CHECK-64-NEXT: retq entry: %0 = tail call i1 @llvm.is.fpclass.f32(float %x, i32 4) ; "-inf" @@ -229,14 +239,18 @@ define i1 @not_is_minus_inf_f(float %x) { ; CHECK-32-LABEL: not_is_minus_inf_f: ; CHECK-32: # %bb.0: # %entry -; CHECK-32-NEXT: cmpl $-8388608, {{[0-9]+}}(%esp) # imm = 0xFF800000 +; CHECK-32-NEXT: flds {{[0-9]+}}(%esp) +; CHECK-32-NEXT: flds {{\.?LCPI[0-9]+_[0-9]+}} +; 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_is_minus_inf_f: ; CHECK-64: # %bb.0: # %entry -; CHECK-64-NEXT: movd %xmm0, %eax -; CHECK-64-NEXT: cmpl $-8388608, %eax # imm = 0xFF800000 +; CHECK-64-NEXT: ucomiss {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0 ; CHECK-64-NEXT: setne %al ; CHECK-64-NEXT: retq entry: