Blame SOURCES/valgrind-3.18.1-amd64-more-spec-rules.patch

4db4a6
commit 595341b150312d2407bd43304449bf39ec3e1fa8
4db4a6
Author: Julian Seward <jseward@acm.org>
4db4a6
Date:   Sat Nov 13 19:59:07 2021 +0100
4db4a6
4db4a6
    amd64 front end: add more spec rules:
4db4a6
    
4db4a6
       S  after SHRQ
4db4a6
       Z  after SHLQ
4db4a6
       NZ after SHLQ
4db4a6
       Z  after SHLL
4db4a6
       S  after SHLL
4db4a6
    
4db4a6
    The lack of at least one of these was observed to cause occasional false
4db4a6
    positives in Memcheck.
4db4a6
    
4db4a6
    Plus add commented-out cases so as to complete the set of 12 rules
4db4a6
    {Z,NZ,S,NS} after {SHRQ,SHLQ,SHLL}.  The commented-out ones are commented
4db4a6
    out because I so far didn't find any use cases for them.
4db4a6
4db4a6
diff --git a/VEX/priv/guest_amd64_helpers.c b/VEX/priv/guest_amd64_helpers.c
4db4a6
index 9d61e7a0f..ba71c1b62 100644
4db4a6
--- a/VEX/priv/guest_amd64_helpers.c
4db4a6
+++ b/VEX/priv/guest_amd64_helpers.c
4db4a6
@@ -1823,16 +1823,26 @@ IRExpr* guest_amd64_spechelper ( const HChar* function_name,
4db4a6
       /*---------------- SHRQ ----------------*/
4db4a6
 
4db4a6
       if (isU64(cc_op, AMD64G_CC_OP_SHRQ) && isU64(cond, AMD64CondZ)) {
4db4a6
-         /* SHRQ, then Z --> test dep1 == 0 */
4db4a6
+         /* SHRQ, then Z --> test result[63:0] == 0 */
4db4a6
          return unop(Iop_1Uto64,
4db4a6
                      binop(Iop_CmpEQ64, cc_dep1, mkU64(0)));
4db4a6
       }
4db4a6
       if (isU64(cc_op, AMD64G_CC_OP_SHRQ) && isU64(cond, AMD64CondNZ)) {
4db4a6
-         /* SHRQ, then NZ --> test dep1 != 0 */
4db4a6
+         /* SHRQ, then NZ --> test result[63:0] != 0 */
4db4a6
          return unop(Iop_1Uto64,
4db4a6
                      binop(Iop_CmpNE64, cc_dep1, mkU64(0)));
4db4a6
       }
4db4a6
 
4db4a6
+      if (isU64(cc_op, AMD64G_CC_OP_SHRQ) && isU64(cond, AMD64CondS)) {
4db4a6
+         /* SHRQ, then S --> (ULong)result[63] (result is in dep1) */
4db4a6
+         return binop(Iop_Shr64, cc_dep1, mkU8(63));
4db4a6
+      }
4db4a6
+      // No known test case for this, hence disabled:
4db4a6
+      //if (isU64(cc_op, AMD64G_CC_OP_SHRQ) && isU64(cond, AMD64CondNS)) {
4db4a6
+      //   /* SHRQ, then NS --> (ULong) ~ result[63] */
4db4a6
+      //   vassert(0);
4db4a6
+      //}
4db4a6
+
4db4a6
       /*---------------- SHRL ----------------*/
4db4a6
 
4db4a6
       if (isU64(cc_op, AMD64G_CC_OP_SHRL) && isU64(cond, AMD64CondZ)) {
4db4a6
@@ -1881,6 +1891,52 @@ IRExpr* guest_amd64_spechelper ( const HChar* function_name,
4db4a6
       //                     mkU32(0)));
4db4a6
       //}
4db4a6
 
4db4a6
+      /*---------------- SHLQ ----------------*/
4db4a6
+
4db4a6
+      if (isU64(cc_op, AMD64G_CC_OP_SHLQ) && isU64(cond, AMD64CondZ)) {
4db4a6
+         /* SHLQ, then Z --> test dep1 == 0 */
4db4a6
+         return unop(Iop_1Uto64,
4db4a6
+                     binop(Iop_CmpEQ64, cc_dep1, mkU64(0)));
4db4a6
+      }
4db4a6
+      if (isU64(cc_op, AMD64G_CC_OP_SHLQ) && isU64(cond, AMD64CondNZ)) {
4db4a6
+         /* SHLQ, then NZ --> test dep1 != 0 */
4db4a6
+         return unop(Iop_1Uto64,
4db4a6
+                     binop(Iop_CmpNE64, cc_dep1, mkU64(0)));
4db4a6
+      }
4db4a6
+
4db4a6
+      //if (isU64(cc_op, AMD64G_CC_OP_SHLQ) && isU64(cond, AMD64CondS)) {
4db4a6
+      //   /* SHLQ, then S --> (ULong)result[63] */
4db4a6
+      //   vassert(0);
4db4a6
+      //}
4db4a6
+      //if (isU64(cc_op, AMD64G_CC_OP_SHLQ) && isU64(cond, AMD64CondNS)) {
4db4a6
+      //   /* SHLQ, then NS --> (ULong) ~ result[63] */
4db4a6
+      //   vassert(0);
4db4a6
+      //}
4db4a6
+
4db4a6
+      /*---------------- SHLL ----------------*/
4db4a6
+
4db4a6
+      if (isU64(cc_op, AMD64G_CC_OP_SHLL) && isU64(cond, AMD64CondZ)) {
4db4a6
+         /* SHLL, then Z --> test result[31:0] == 0 */
4db4a6
+         return unop(Iop_1Uto64,
4db4a6
+                     binop(Iop_CmpEQ32, unop(Iop_64to32, cc_dep1),
4db4a6
+                           mkU32(0)));
4db4a6
+      }
4db4a6
+      //if (isU64(cc_op, AMD64G_CC_OP_SHLL) && isU64(cond, AMD64CondNZ)) {
4db4a6
+      //   /* SHLL, then NZ --> test dep1 != 0 */
4db4a6
+      //   vassert(0);
4db4a6
+      //}
4db4a6
+
4db4a6
+      if (isU64(cc_op, AMD64G_CC_OP_SHLL) && isU64(cond, AMD64CondS)) {
4db4a6
+         /* SHLL, then S --> (ULong)result[31] */
4db4a6
+         return binop(Iop_And64,
4db4a6
+                      binop(Iop_Shr64, cc_dep1, mkU8(31)),
4db4a6
+                      mkU64(1));
4db4a6
+      }
4db4a6
+      //if (isU64(cc_op, AMD64G_CC_OP_SHLL) && isU64(cond, AMD64CondNS)) {
4db4a6
+      //   /* SHLL, then NS --> (ULong) ~ result[31] */
4db4a6
+      //   vassert(0);
4db4a6
+      //}
4db4a6
+
4db4a6
       /*---------------- COPY ----------------*/
4db4a6
       /* This can happen, as a result of amd64 FP compares: "comisd ... ;
4db4a6
          jbe" for example. */