]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
Add folding rules for Clz32 and Clz64. See bug 243404 comment 52.
authorJulian Seward <jseward@acm.org>
Mon, 7 Mar 2011 18:34:34 +0000 (18:34 +0000)
committerJulian Seward <jseward@acm.org>
Mon, 7 Mar 2011 18:34:34 +0000 (18:34 +0000)
(Florian Krohn, britzel@acm.org).

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

VEX/priv/ir_opt.c

index a205faeae5c03b03d77d1e82e6e1b2b208925c7f..7d26d4dd2e189ac367f4ab382f89344c506eb4d4 100644 (file)
@@ -956,6 +956,31 @@ static IRExpr* mkOnesOfPrimopResultType ( IROp op )
    }
 }
 
+/* Helpers for folding Clz32/64. */
+static UInt fold_Clz64 ( ULong value )
+{
+   UInt i;
+   vassert(value != 0ULL); /* no defined semantics for arg==0 */
+   for (i = 0; i < 64; ++i) {
+      if (value & (((ULong)1) << (63 - i))) return i;
+   }
+   vassert(0);
+   /*NOTREACHED*/
+   return 0;
+}
+
+static UInt fold_Clz32 ( UInt value )
+{
+   UInt i;
+   vassert(value != 0); /* no defined semantics for arg==0 */
+   for (i = 0; i < 32; ++i) {
+      if (value & (((UInt)1) << (31 - i))) return i;
+   }
+   vassert(0);
+   /*NOTREACHED*/
+   return 0;
+}
+
 
 static IRExpr* fold_Expr ( IRExpr* e )
 {
@@ -1154,6 +1179,19 @@ static IRExpr* fold_Expr ( IRExpr* e )
             break;
          }
 
+         case Iop_Clz32: {
+            UInt u32 = e->Iex.Unop.arg->Iex.Const.con->Ico.U32;
+            if (u32 != 0)
+               e2 = IRExpr_Const(IRConst_U32(fold_Clz32(u32)));
+            break;
+         }
+         case Iop_Clz64: {
+            ULong u64 = e->Iex.Unop.arg->Iex.Const.con->Ico.U64;
+            if (u64 != 0ULL)
+               e2 = IRExpr_Const(IRConst_U64(fold_Clz64(u64)));
+            break;
+         }
+
          default: 
             goto unhandled;
       }