From: Mark Wielaard Date: Thu, 21 Feb 2019 16:21:53 +0000 (+0100) Subject: memcheck powerpc subfe x, x, x initializes x to 0 or -1 based on CA X-Git-Tag: VALGRIND_3_15_0~71 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=256cf43c5eadb28edb45436aca6fda8ee55eb10e;p=thirdparty%2Fvalgrind.git memcheck powerpc subfe x, x, x initializes x to 0 or -1 based on CA GCC might use subfe x, x, x to initialize x to 0 or -1, based on whether the carry flag is set. This happens in some cases when g++ compiles resetting a unique_ptr. The "trick" used by the compiler is that it can AND a pointer with the register x (now 0x0 or 0xffffffff) to set something to NULL or to the given pointer. subfe is implemented as rD = (log not)rA + rB + XER[CA] if we instead implement it as rD = rB - rA - (XER[CA] ^ 1) then memcheck can see that rB and Ra cancel each other out if they are the same. https://bugs.kde.org/show_bug.cgi?id=404054 --- diff --git a/NEWS b/NEWS index 4a75a0aa3d..3dfdacf426 100644 --- a/NEWS +++ b/NEWS @@ -102,6 +102,7 @@ where XXXXXX is the bug number as listed below. 402519 POWER 3.0 addex instruction incorrectly implemented 402781 Redo the cache used to process indirect branch targets 403552 s390x: wrong facility bit checked for vector facility +404054 memcheck powerpc subfe x, x, x initializes x to 0 or -1 based on CA n-i-bz add syswrap for PTRACE_GET|SET_THREAD_AREA on amd64. n-i-bz Fix callgrind_annotate non deterministic order for equal total diff --git a/VEX/priv/guest_ppc_toIR.c b/VEX/priv/guest_ppc_toIR.c index e207642682..00ae6df2d6 100644 --- a/VEX/priv/guest_ppc_toIR.c +++ b/VEX/priv/guest_ppc_toIR.c @@ -5361,11 +5361,15 @@ static Bool dis_int_arith ( UInt theInstr ) flag_OE ? "o" : "", flag_rC ? ".":"", rD_addr, rA_addr, rB_addr); // rD = (log not)rA + rB + XER[CA] + // ==> + // rD = rB - rA - (XER[CA] ^ 1) assign( old_xer_ca, mkWidenFrom32(ty, getXER_CA_32(), False) ); - assign( rD, binop( mkSzOp(ty, Iop_Add8), - unop( mkSzOp(ty, Iop_Not8), mkexpr(rA)), - binop( mkSzOp(ty, Iop_Add8), - mkexpr(rB), mkexpr(old_xer_ca))) ); + assign( rD, binop( mkSzOp(ty, Iop_Sub8), + binop( mkSzOp(ty, Iop_Sub8), + mkexpr(rB), mkexpr(rA)), + binop(mkSzOp(ty, Iop_Xor8), + mkexpr(old_xer_ca), + mkSzImm(ty, 1))) ); set_XER_CA_CA32( ty, PPCG_FLAG_OP_SUBFE, mkexpr(rD), mkexpr(rA), mkexpr(rB), mkexpr(old_xer_ca) );