]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
Constant folding for Iop_CmpORD.. and Iop_8HLto16, Iop16HLto32. (BZ 506211)
authorFlorian Krohm <flo2030@eich-krohm.de>
Thu, 17 Jul 2025 12:23:22 +0000 (12:23 +0000)
committerFlorian Krohm <flo2030@eich-krohm.de>
Thu, 17 Jul 2025 12:23:22 +0000 (12:23 +0000)
Part of fixing https://bugs.kde.org/show_bug.cgi?id=506211

VEX/priv/ir_opt.c
none/tests/iropt-test/binary.c
none/tests/iropt-test/irops.tab

index 4653704d3e3b7adbcfe90c924ffe5f318f8be189..8e4d95692dd6763dbe275a115c83bbcc4ebcbf4d 100644 (file)
@@ -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
index 2c815c81368e4c5119d2d56034d0ded56aa90347..1ec2d77e3d09421c9c7126ea809dc2150d41c715 100644 (file)
@@ -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;
index efae871fbfa439e985a05bd27dbfce1e5cc53860..68f8cc8860e82da777f6dd24f8e870988f91d212 100644 (file)
    { 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