diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp --- a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp @@ -6749,7 +6749,6 @@ // Convert a sign-bit test of an FP value into a cast and integer compare. // TODO: Simplify if the copysign constant is 0.0 or NaN. // TODO: Handle non-zero compare constants. - // TODO: Handle other predicates. const APFloat *C; if (match(Op0, m_OneUse(m_Intrinsic(m_APFloat(C), m_Value(X)))) && @@ -6764,6 +6763,12 @@ return new ICmpInst(ICmpInst::ICMP_SLT, IntX, ConstantInt::getNullValue(IntType)); } + // copysign(non-zero constant, X) > 0.0 --> (bitcast X) > 0 + if (Pred == FCmpInst::FCMP_OGT) { + Value *IntX = Builder.CreateBitCast(X, IntType); + return new ICmpInst(ICmpInst::ICMP_SGT, IntX, + ConstantInt::getNullValue(IntType)); + } } if (I.getType()->isVectorTy()) diff --git a/llvm/test/Transforms/InstCombine/fcmp.ll b/llvm/test/Transforms/InstCombine/fcmp.ll --- a/llvm/test/Transforms/InstCombine/fcmp.ll +++ b/llvm/test/Transforms/InstCombine/fcmp.ll @@ -605,12 +605,10 @@ ret <2 x i1> %r } -; TODO: Handle different predicates. - define i1 @is_signbit_clear(double %x) { ; CHECK-LABEL: @is_signbit_clear( -; CHECK-NEXT: [[S:%.*]] = call double @llvm.copysign.f64(double -4.200000e+01, double [[X:%.*]]) -; CHECK-NEXT: [[R:%.*]] = fcmp ogt double [[S]], 0.000000e+00 +; CHECK-NEXT: [[TMP1:%.*]] = bitcast double [[X:%.*]] to i64 +; CHECK-NEXT: [[R:%.*]] = icmp sgt i64 [[TMP1]], 0 ; CHECK-NEXT: ret i1 [[R]] ; %s = call double @llvm.copysign.f64(double -42.0, double %x)