From: Florian Krohm Date: Thu, 17 Jul 2025 12:23:22 +0000 (+0000) Subject: Constant folding for Iop_CmpORD.. and Iop_8HLto16, Iop16HLto32. (BZ 506211) X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=c84404c4f8ba52edd9bd3c68fae316510adc1a90;p=thirdparty%2Fvalgrind.git Constant folding for Iop_CmpORD.. and Iop_8HLto16, Iop16HLto32. (BZ 506211) Part of fixing https://bugs.kde.org/show_bug.cgi?id=506211 --- diff --git a/VEX/priv/ir_opt.c b/VEX/priv/ir_opt.c index 4653704d3..8e4d95692 100644 --- a/VEX/priv/ir_opt.c +++ b/VEX/priv/ir_opt.c @@ -2339,8 +2339,64 @@ static IRExpr* fold_Expr_WRK ( IRExpr** env, IRExpr* e ) e2 = IRExpr_Const(IRConst_U32(r)); break; } + case Iop_CmpORD64S: { + /* very paranoid */ + ULong u64a = e->Iex.Binop.arg1->Iex.Const.con->Ico.U64; + ULong u64b = e->Iex.Binop.arg2->Iex.Const.con->Ico.U64; + Long s64a = (Long)u64a; + Long s64b = (Long)u64b; + Int r = 0x2; /* EQ */ + if (s64a < s64b) { + r = 0x8; /* LT */ + } + else if (s64a > s64b) { + r = 0x4; /* GT */ + } + e2 = IRExpr_Const(IRConst_U64(r)); + break; + } + case Iop_CmpORD32U: { + UInt u32a = e->Iex.Binop.arg1->Iex.Const.con->Ico.U32; + UInt u32b = e->Iex.Binop.arg2->Iex.Const.con->Ico.U32; + Int r = 0x2; /* EQ */ + if (u32a < u32b) { + r = 0x8; /* LT */ + } + else if (u32a > u32b) { + r = 0x4; /* GT */ + } + e2 = IRExpr_Const(IRConst_U32(r)); + break; + } + case Iop_CmpORD64U: { + ULong u64a = e->Iex.Binop.arg1->Iex.Const.con->Ico.U64; + ULong u64b = e->Iex.Binop.arg2->Iex.Const.con->Ico.U64; + Int r = 0x2; /* EQ */ + if (u64a < u64b) { + r = 0x8; /* LT */ + } + else if (u64a > u64b) { + r = 0x4; /* GT */ + } + e2 = IRExpr_Const(IRConst_U64(r)); + break; + } /* -- nHLto2n -- */ + case Iop_8HLto16: + e2 = IRExpr_Const(IRConst_U16(toUShort( + (((UInt)(e->Iex.Binop.arg1 + ->Iex.Const.con->Ico.U8)) << 8) + | ((UInt)(e->Iex.Binop.arg2->Iex.Const.con->Ico.U8))) + )); + break; + case Iop_16HLto32: + e2 = IRExpr_Const(IRConst_U32( + (((UInt)(e->Iex.Binop.arg1 + ->Iex.Const.con->Ico.U16)) << 16) + | ((UInt)(e->Iex.Binop.arg2->Iex.Const.con->Ico.U16)) + )); + break; case Iop_32HLto64: e2 = IRExpr_Const(IRConst_U64( (((ULong)(e->Iex.Binop.arg1 diff --git a/none/tests/iropt-test/binary.c b/none/tests/iropt-test/binary.c index 2c815c813..1ec2d77e3 100644 --- a/none/tests/iropt-test/binary.c +++ b/none/tests/iropt-test/binary.c @@ -233,9 +233,11 @@ check_result(const irop_t *op, const test_data_t *data) break; case Iop_CmpLT32S: { - int32_t opnd_ls = (int32_t)(opnd_l & UINT32_MAX); - int32_t opnd_rs = (int32_t)(opnd_r & UINT32_MAX); - expected = opnd_ls < opnd_rs; + uint32_t u32l = opnd_l & UINT32_MAX; + uint32_t u32r = opnd_r & UINT32_MAX; + int32_t s32l = (int32_t)u32l; + int32_t s32r = (int32_t)u32r; + expected = s32l < s32r; break; } @@ -249,9 +251,11 @@ check_result(const irop_t *op, const test_data_t *data) break; case Iop_CmpLE32S: { - int32_t opnd_ls = (int32_t)(opnd_l & UINT32_MAX); - int32_t opnd_rs = (int32_t)(opnd_r & UINT32_MAX); - expected = opnd_ls <= opnd_rs; + uint32_t u32l = opnd_l & UINT32_MAX; + uint32_t u32r = opnd_r & UINT32_MAX; + int32_t s32l = (int32_t)u32l; + int32_t s32r = (int32_t)u32r; + expected = s32l <= s32r; break; } @@ -259,9 +263,22 @@ check_result(const irop_t *op, const test_data_t *data) expected = (int64_t)opnd_l <= (int64_t)opnd_r; break; + case Iop_CmpORD32U: + case Iop_CmpORD64U: + expected = (opnd_l < opnd_r) ? 8 : (opnd_l > opnd_r) ? 4 : 2; + break; + case Iop_CmpORD32S: { - int32_t opnd_ls = (int32_t)(opnd_l & UINT32_MAX); - int32_t opnd_rs = (int32_t)(opnd_r & UINT32_MAX); + uint32_t u32l = opnd_l & UINT32_MAX; + uint32_t u32r = opnd_r & UINT32_MAX; + int32_t s32l = (int32_t)u32l; + int32_t s32r = (int32_t)u32r; + expected = (s32l < s32r) ? 8 : (s32l > s32r) ? 4 : 2; + break; + } + case Iop_CmpORD64S: { + int64_t opnd_ls = (int64_t)opnd_l; + int64_t opnd_rs = (int64_t)opnd_r; expected = (opnd_ls < opnd_rs) ? 8 : (opnd_ls > opnd_rs) ? 4 : 2; break; } @@ -272,6 +289,14 @@ check_result(const irop_t *op, const test_data_t *data) expected = opnd_l > opnd_r ? opnd_l : opnd_r; break; + case Iop_8HLto16: + expected = (opnd_l << 8) | opnd_r; + break; + + case Iop_16HLto32: + expected = (opnd_l << 16) | opnd_r; + break; + case Iop_32HLto64: expected = (opnd_l << 32) | opnd_r; break; diff --git a/none/tests/iropt-test/irops.tab b/none/tests/iropt-test/irops.tab index efae871fb..68f8cc886 100644 --- a/none/tests/iropt-test/irops.tab +++ b/none/tests/iropt-test/irops.tab @@ -234,15 +234,15 @@ { OPNAME(ExpCmpNE32), Ity_I1, 2, Ity_I32, Ity_I32 }, { OPNAME(ExpCmpNE64), Ity_I1, 2, Ity_I64, Ity_I64 }, -// { OPNAME(CmpORD32U), Ity_I32, 2, Ity_I32, Ity_I32 }, // no folding yet -// { OPNAME(CmpORD64U), Ity_I64, 2, Ity_I64, Ity_I64 }, // no folding yet + { OPNAME(CmpORD32U), Ity_I32, 2, Ity_I32, Ity_I32 }, + { OPNAME(CmpORD64U), Ity_I64, 2, Ity_I64, Ity_I64 }, { OPNAME(CmpORD32S), Ity_I32, 2, Ity_I32, Ity_I32 }, -// { OPNAME(CmpORD64S), Ity_I64, 2, Ity_I64, Ity_I64 }, // no folding yet + { OPNAME(CmpORD64S), Ity_I64, 2, Ity_I64, Ity_I64 }, { OPNAME(Max32U), Ity_I32, 2, Ity_I32, Ity_I32 }, -// { OPNAME(8HLto16), Ity_I16, 2, Ity_I8, Ity_I8 }, // no folding yet -// { OPNAME(16HLto32), Ity_I32, 2, Ity_I16, Ity_I16 }, // no folding yet + { OPNAME(8HLto16), Ity_I16, 2, Ity_I8, Ity_I8 }, + { OPNAME(16HLto32), Ity_I32, 2, Ity_I16, Ity_I16 }, { OPNAME(32HLto64), Ity_I64, 2, Ity_I32, Ity_I32 }, // { OPNAME(64HLto128), Ity_I128, 2, Ity_I64, Ity_I64 }, // 128 bit