Index: lib/Transforms/InstCombine/InstCombineAndOrXor.cpp =================================================================== --- lib/Transforms/InstCombine/InstCombineAndOrXor.cpp +++ lib/Transforms/InstCombine/InstCombineAndOrXor.cpp @@ -1748,7 +1748,7 @@ // E.g. (icmp sgt x, n) | (icmp slt x, 0) --> icmp ugt x, n if (Value *V = simplifyRangeCheck(RHS, LHS, /*Inverted=*/true)) return V; - + // This only handles icmp of constants: (icmp1 A, C1) | (icmp2 B, C2). if (!LHSCst || !RHSCst) return nullptr; @@ -2748,5 +2748,17 @@ } } + // If we are XORing the sign bit of a floating-point value, convert + // this to fsub from -0.0, then cast back to integer. + ConstantInt *CI; + if (CastInst *Op0C = dyn_cast(Op0)) { + if (isa(Op0C) && Op0->getType()->isFloatingPointTy() && + match(Op1, m_ConstantInt(CI)) && CI->isMinValue(true)) { + Value *Call = Builder->CreateFSub( + ConstantFP::getNegativeZero(Op0->getType()), Op0); + return CastInst::CreateBitOrPointerCast(Call, I.getType()); + } + } + return Changed ? &I : nullptr; }