@@ -276,7 +276,7 @@ static cl::opt<bool>
276276static cl::opt<bool >
277277 ClHandleICmpExact (" msan-handle-icmp-exact" ,
278278 cl::desc (" exact handling of relational integer ICmp" ),
279- cl::Hidden, cl::init(false ));
279+ cl::Hidden, cl::init(true ));
280280
281281static cl::opt<bool > ClHandleLifetimeIntrinsics (
282282 " msan-handle-lifetime-intrinsics" ,
@@ -2694,40 +2694,6 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> {
26942694 setOriginForNaryOp (I);
26952695 }
26962696
2697- // / Build the lowest possible value of V, taking into account V's
2698- // / uninitialized bits.
2699- Value *getLowestPossibleValue (IRBuilder<> &IRB, Value *A, Value *Sa,
2700- bool isSigned) {
2701- if (isSigned) {
2702- // Split shadow into sign bit and other bits.
2703- Value *SaOtherBits = IRB.CreateLShr (IRB.CreateShl (Sa, 1 ), 1 );
2704- Value *SaSignBit = IRB.CreateXor (Sa, SaOtherBits);
2705- // Maximise the undefined shadow bit, minimize other undefined bits.
2706- return IRB.CreateOr (IRB.CreateAnd (A, IRB.CreateNot (SaOtherBits)),
2707- SaSignBit);
2708- } else {
2709- // Minimize undefined bits.
2710- return IRB.CreateAnd (A, IRB.CreateNot (Sa));
2711- }
2712- }
2713-
2714- // / Build the highest possible value of V, taking into account V's
2715- // / uninitialized bits.
2716- Value *getHighestPossibleValue (IRBuilder<> &IRB, Value *A, Value *Sa,
2717- bool isSigned) {
2718- if (isSigned) {
2719- // Split shadow into sign bit and other bits.
2720- Value *SaOtherBits = IRB.CreateLShr (IRB.CreateShl (Sa, 1 ), 1 );
2721- Value *SaSignBit = IRB.CreateXor (Sa, SaOtherBits);
2722- // Minimise the undefined shadow bit, maximise other undefined bits.
2723- return IRB.CreateOr (IRB.CreateAnd (A, IRB.CreateNot (SaSignBit)),
2724- SaOtherBits);
2725- } else {
2726- // Maximize undefined bits.
2727- return IRB.CreateOr (A, Sa);
2728- }
2729- }
2730-
27312697 // / Instrument relational comparisons.
27322698 // /
27332699 // / This function does exact shadow propagation for all relational
@@ -2750,12 +2716,29 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> {
27502716 // its undefined bits. Let [b0, b1] be the interval of possible values of B.
27512717 // Then (A cmp B) is defined iff (a0 cmp b1) == (a1 cmp b0).
27522718 bool IsSigned = I.isSigned ();
2753- Value *S1 = IRB.CreateICmp (I.getPredicate (),
2754- getLowestPossibleValue (IRB, A, Sa, IsSigned),
2755- getHighestPossibleValue (IRB, B, Sb, IsSigned));
2756- Value *S2 = IRB.CreateICmp (I.getPredicate (),
2757- getHighestPossibleValue (IRB, A, Sa, IsSigned),
2758- getLowestPossibleValue (IRB, B, Sb, IsSigned));
2719+
2720+ auto GetMinMaxUnsigned = [&](Value *V, Value *S) {
2721+ if (IsSigned) {
2722+ // Map from signed range to unsigned range. Relation A vs B should be
2723+ // preserved if checked with `getUnsignedPredicate()`.
2724+ // Calcualting Amin, Amax, Bmin, Bmax also will not be affected, as they
2725+ // are created by effectively adding/substructing from A or B a value,
2726+ // derived from shadow, which can't result in overflow.
2727+ APInt MinVal =
2728+ APInt::getSignedMinValue (V->getType ()->getScalarSizeInBits ());
2729+ V = IRB.CreateXor (V, ConstantInt::get (V->getType (), MinVal));
2730+ }
2731+ // Minimize undefined bits.
2732+ Value *Min = IRB.CreateAnd (V, IRB.CreateNot (S));
2733+ Value *Max = IRB.CreateOr (V, S);
2734+ return std::make_pair (Min, Max);
2735+ };
2736+
2737+ auto [Amin, Amax] = GetMinMaxUnsigned (A, Sa);
2738+ auto [Bmin, Bmax] = GetMinMaxUnsigned (B, Sb);
2739+ Value *S1 = IRB.CreateICmp (I.getUnsignedPredicate (), Amin, Bmax);
2740+ Value *S2 = IRB.CreateICmp (I.getUnsignedPredicate (), Amax, Bmin);
2741+
27592742 Value *Si = IRB.CreateXor (S1, S2);
27602743 setShadow (&I, Si);
27612744 setOriginForNaryOp (I);
0 commit comments