|
From: <sv...@va...> - 2011-03-07 18:34:41
|
Author: sewardj
Date: 2011-03-07 18:34:34 +0000 (Mon, 07 Mar 2011)
New Revision: 2106
Log:
Add folding rules for Clz32 and Clz64. See bug 243404 comment 52.
(Florian Krohn, br...@ac...).
Modified:
trunk/priv/ir_opt.c
Modified: trunk/priv/ir_opt.c
===================================================================
--- trunk/priv/ir_opt.c 2011-03-07 16:04:07 UTC (rev 2105)
+++ trunk/priv/ir_opt.c 2011-03-07 18:34:34 UTC (rev 2106)
@@ -956,7 +956,32 @@
}
}
+/* 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 )
{
Int shift;
@@ -1154,6 +1179,19 @@
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;
}
|