|
From: <sv...@va...> - 2005-10-07 12:13:25
|
Author: sewardj
Date: 2005-10-07 13:13:21 +0100 (Fri, 07 Oct 2005)
New Revision: 4890
Log:
ppc32 only: improve handling of CmpORD32S, so as to avoid false
positives from ppc code of the form "cmpi %reg,0 ; branch-if-negative
.." where the top bit of %reg is defined but not all of the other bits
are (common-ish enough to cause a considerable number of false
positives if not done right).
Modified:
trunk/memcheck/mc_translate.c
Modified: trunk/memcheck/mc_translate.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- trunk/memcheck/mc_translate.c 2005-10-07 12:11:12 UTC (rev 4889)
+++ trunk/memcheck/mc_translate.c 2005-10-07 12:13:21 UTC (rev 4890)
@@ -687,7 +687,27 @@
=20
The "& (7<<1)" reflects the fact that all result bits except 3,2,1
are zero and therefore defined (viz, zero).
+
+ Also deal with a special case better:
+
+ CmpORD32S(x,0)
+
+ Here, bit 3 (LT) of the result is a copy of the top bit of x and
+ will be defined even if the rest of x isn't. In which case we do:
+
+ CmpORD32S#(x,x#,0,{impliedly 0}#)
+ =3D PCast(x#) & (3<<1) -- standard interp for GT,EQ
+ | (x# >> 31) << 3 -- LT =3D x#[31]
+
*/
+static Bool isZeroU32 ( IRAtom* e )
+{
+ return
+ toBool( e->tag =3D=3D Iex_Const
+ && e->Iex.Const.con->tag =3D=3D Ico_U32
+ && e->Iex.Const.con->Ico.U32 =3D=3D 0 );
+}
+
static IRAtom* doCmpORD32 ( MCEnv* mce,
IROp cmp_op,
IRAtom* xxhash, IRAtom* yyhash,=20
@@ -701,16 +721,45 @@
tl_assert(sameKindedAtoms(yyhash,yy));
tl_assert(cmp_op =3D=3D Iop_CmpORD32S || cmp_op =3D=3D Iop_CmpORD32U)=
;
=20
- return=20
- binop(=20
- Iop_And32,=20
- assignNew(=20
- mce,Ity_I32,
+ if (0) {
+ ppIROp(cmp_op); VG_(printf)(" ");=20
+ ppIRExpr(xx); VG_(printf)(" "); ppIRExpr( yy ); VG_(printf)("\n");
+ }
+
+ if (isZeroU32(yy)) {
+ /* fancy interpretation */
+ /* if yy is zero, then it must be fully defined (zero#). */
+ tl_assert(isZeroU32(yyhash));
+ return
+ binop(
+ Iop_Or32,
+ assignNew(
+ mce,Ity_I32,
+ binop(
+ Iop_And32,
+ mkPCastTo(mce,Ity_I32, xxhash),=20
+ mkU32(3<<1)
+ )),
+ assignNew(
+ mce,Ity_I32,
+ binop(
+ Iop_Shl32,
+ assignNew(
+ mce,Ity_I32,
+ binop(Iop_Shr32, xxhash, mkU8(31))),
+ mkU8(3)
+ ))
+ );
+ } else {
+ /* standard interpretation */
+ return=20
+ binop(=20
+ Iop_And32,=20
mkPCastTo( mce,Ity_I32,
- assignNew( mce,Ity_I32,
- mkUifU32(mce, xxhash,yyhash))) ),
- mkU32(7<<1)
- );
+ mkUifU32(mce, xxhash,yyhash)),
+ mkU32(7<<1)
+ );
+ }
}
=20
=20
|