]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
A couple of IR simplification hacks for the amd64 front end, so as to
authorJulian Seward <jseward@acm.org>
Sun, 21 May 2006 01:02:31 +0000 (01:02 +0000)
committerJulian Seward <jseward@acm.org>
Sun, 21 May 2006 01:02:31 +0000 (01:02 +0000)
avoid false errors from memcheck.  Analogous to some of the recent
bunch of commits to x86 front end.

git-svn-id: svn://svn.valgrind.org/vex/trunk@1620

VEX/priv/guest-amd64/ghelpers.c
VEX/priv/ir/iropt.c

index 8e8c707dde6be9f270c09aed66b522aaad1a470d..24c96ff227283c55635d8f2405985a2286e33dc1 100644 (file)
@@ -1132,6 +1132,19 @@ IRExpr* guest_amd64_spechelper ( HChar* function_name,
                                         mkU64(0)));
       }
 
+      if (isU64(cc_op, AMD64G_CC_OP_LOGICB) && isU64(cond, AMD64CondS)) {
+         /* this is an idiom gcc sometimes uses to find out if the top
+            bit of a byte register is set: eg testb %al,%al; js ..
+            Since it just depends on the top bit of the byte, extract
+            that bit and explicitly get rid of all the rest.  This
+            helps memcheck avoid false positives in the case where any
+            of the other bits in the byte are undefined. */
+         /* byte and/or/xor, then S --> (UInt)result[7] */
+         return binop(Iop_And64,
+                      binop(Iop_Shr64,cc_dep1,mkU8(7)),
+                      mkU64(1));
+      }
+
       /*---------------- INCB ----------------*/
 
       if (isU64(cc_op, AMD64G_CC_OP_INCB) && isU64(cond, AMD64CondLE)) {
index 94462d40218272a7f2563f2ca43d359e353b85e3..ea70bbda6ec0793d3fc64f19a7e0c318ff2f4c38 100644 (file)
@@ -1419,6 +1419,17 @@ static IRExpr* fold_Expr ( IRExpr* e )
                               IRExpr_Const(IRConst_U8(1)));
          } else
 
+         /* Add64(t,t) ==> t << 1;  rationale as for Add32(t,t) above. */
+         if (e->Iex.Binop.op == Iop_Add64
+             && e->Iex.Binop.arg1->tag == Iex_Tmp
+             && e->Iex.Binop.arg2->tag == Iex_Tmp
+             && e->Iex.Binop.arg1->Iex.Tmp.tmp 
+                == e->Iex.Binop.arg2->Iex.Tmp.tmp) {
+            e2 = IRExpr_Binop(Iop_Shl64,
+                              e->Iex.Binop.arg1,
+                              IRExpr_Const(IRConst_U8(1)));
+         } else
+
          /* Or64/Add64(x,0) ==> x */
          if ((e->Iex.Binop.op == Iop_Add64 || e->Iex.Binop.op == Iop_Or64)
              && e->Iex.Binop.arg2->tag == Iex_Const