]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
x86 front end: add spec rules for S/NS after SUBL(x, 0)
authorJulian Seward <jseward@acm.org>
Fri, 17 Aug 2018 06:37:06 +0000 (08:37 +0200)
committerJulian Seward <jseward@acm.org>
Fri, 17 Aug 2018 06:37:06 +0000 (08:37 +0200)
This reduces Memcheck's false-positive level on clang -O2 generated code.

VEX/priv/guest_x86_helpers.c

index 250b1dbba5b6c4986de0ad5359c336a71f90b2cf..78be0662f6843b2a01d30d3ae9f9ff7b27e91177 100644 (file)
@@ -856,6 +856,7 @@ IRExpr* guest_x86_spechelper ( const HChar* function_name,
 
       /*---------------- SUBL ----------------*/
 
+      /* 4, 5 */
       if (isU32(cc_op, X86G_CC_OP_SUBL) && isU32(cond, X86CondZ)) {
          /* long sub/cmp, then Z --> test dst==src */
          return unop(Iop_1Uto32,
@@ -867,6 +868,7 @@ IRExpr* guest_x86_spechelper ( const HChar* function_name,
                      binop(Iop_CmpNE32, cc_dep1, cc_dep2));
       }
 
+      /* 12, 13 */
       if (isU32(cc_op, X86G_CC_OP_SUBL) && isU32(cond, X86CondL)) {
          /* long sub/cmp, then L (signed less than) 
             --> test dst <s src */
@@ -882,6 +884,7 @@ IRExpr* guest_x86_spechelper ( const HChar* function_name,
                       mkU32(1));
       }
 
+      /* 14, 15 */
       if (isU32(cc_op, X86G_CC_OP_SUBL) && isU32(cond, X86CondLE)) {
          /* long sub/cmp, then LE (signed less than or equal)
             --> test dst <=s src */
@@ -898,6 +901,7 @@ IRExpr* guest_x86_spechelper ( const HChar* function_name,
                       mkU32(1));
       }
 
+      /* 6, 7 */
       if (isU32(cc_op, X86G_CC_OP_SUBL) && isU32(cond, X86CondBE)) {
          /* long sub/cmp, then BE (unsigned less than or equal)
             --> test dst <=u src */
@@ -913,6 +917,7 @@ IRExpr* guest_x86_spechelper ( const HChar* function_name,
                       mkU32(1));
       }
 
+      /* 2, 3 */
       if (isU32(cc_op, X86G_CC_OP_SUBL) && isU32(cond, X86CondB)) {
          /* long sub/cmp, then B (unsigned less than)
             --> test dst <u src */
@@ -928,6 +933,28 @@ IRExpr* guest_x86_spechelper ( const HChar* function_name,
                       mkU32(1));
       }
 
+      /* 8, 9 */
+      if (isU32(cc_op, X86G_CC_OP_SUBL) && isU32(cond, X86CondS)
+                                        && isU32(cc_dep2, 0)) {
+         /* long sub/cmp of zero, then S --> test (dst-0 <s 0)
+                                         --> test dst <s 0
+                                         --> (UInt)dst[31] */
+         return binop(Iop_And32,
+                      binop(Iop_Shr32,cc_dep1,mkU8(31)),
+                      mkU32(1));
+      }
+      if (isU32(cc_op, X86G_CC_OP_SUBL) && isU32(cond, X86CondNS)
+                                        && isU32(cc_dep2, 0)) {
+         /* long sub/cmp of zero, then NS --> test !(dst-0 <s 0)
+                                          --> test !(dst <s 0)
+                                          --> (UInt) !dst[31] */
+         return binop(Iop_Xor32,
+                      binop(Iop_And32,
+                            binop(Iop_Shr32,cc_dep1,mkU8(31)),
+                            mkU32(1)),
+                mkU32(1));
+      }
+
       if (isU32(cc_op, X86G_CC_OP_SUBL) && isU32(cond, X86CondS)) {
          /* long sub/cmp, then S (negative) --> test (dst-src <s 0) */
          return unop(Iop_1Uto32,