The following example fails with –O2 (passes at -O1) extern "C" int printf(const char *, ...); int signbit(double d) {return *((long long *)&d)<0;} double m0 = -0.; int main() { if ( m0 == 0) { if (signbit(m0) != 0) printf("Passed\n"); else printf("Failed\n"); } } It is a regression since r225660, which was for Bug 17713.
Negative zero; yep, that's a bug. Simplified test case; this should return '1', but 'opt -gvn' will cause it to return '0': @m0 = global double -0.000000e+00, align 8 define i32 @main() { entry: %0 = load double* @m0, align 8 %cmp = fcmp oeq double %0, 0.000000e+00 br i1 %cmp, label %if.then, label %return if.then: ; preds = %entry %1 = bitcast double %0 to i64 %.lobit = lshr i64 %1, 63 %2 = trunc i64 %.lobit to i32 br label %return return: ; preds = %if.then, %entry %retval.0 = phi i32 [ %2, %if.then ], [ 2, %entry ] ret i32 %retval.0 }
Here's the simplest patch I could come up with. If this looks like a good fix to you, I'll submit a patch with test case for review tomorrow. Index: lib/Transforms/Scalar/GVN.cpp =================================================================== --- lib/Transforms/Scalar/GVN.cpp (revision 227320) +++ lib/Transforms/Scalar/GVN.cpp (working copy) @@ -2182,8 +2182,11 @@ // Handle the floating point versions of equality comparisons too. if ((isKnownTrue && Cmp->getPredicate() == CmpInst::FCMP_OEQ) || - (isKnownFalse && Cmp->getPredicate() == CmpInst::FCMP_UNE)) - Worklist.push_back(std::make_pair(Op0, Op1)); + (isKnownFalse && Cmp->getPredicate() == CmpInst::FCMP_UNE)) { + // FP -0.0 and 0.0 compare equal, so we can't propagate that. + if (!isa<ConstantFP>(Op1) || !cast<ConstantFP>(Op1)->isZero()) + Worklist.push_back(std::make_pair(Op0, Op1)); + } // If "A >= B" is known true, replace "A < B" with false everywhere. CmpInst::Predicate NotPred = Cmp->getInversePredicate();
Patch posted for review: http://reviews.llvm.org/D7257 Sunil, Warren - I didn't find Phabricator IDs for you. Please add yourselves if you'd like to comment there.
Fix checked in: http://llvm.org/viewvc/llvm-project?view=revision&revision=227491