]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
Constant folding for various multiplication IROps. (BZ 506211)
authorFlorian Krohm <flo2030@eich-krohm.de>
Thu, 17 Jul 2025 14:04:50 +0000 (14:04 +0000)
committerFlorian Krohm <flo2030@eich-krohm.de>
Thu, 17 Jul 2025 14:04:50 +0000 (14:04 +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 8e4d95692dd6763dbe275a115c83bbcc4ebcbf4d..fa0b76a961443e63aa5e5ed0a5362f56f5a8189c 100644 (file)
@@ -2067,6 +2067,16 @@ static IRExpr* fold_Expr_WRK ( IRExpr** env, IRExpr* e )
             }
 
             /* -- Mul -- */
+            case Iop_Mul8:
+               e2 = IRExpr_Const(IRConst_U8(toUChar(
+                       (e->Iex.Binop.arg1->Iex.Const.con->Ico.U8
+                        * e->Iex.Binop.arg2->Iex.Const.con->Ico.U8))));
+               break;
+            case Iop_Mul16:
+               e2 = IRExpr_Const(IRConst_U16(toUShort(
+                       (e->Iex.Binop.arg1->Iex.Const.con->Ico.U16
+                        * e->Iex.Binop.arg2->Iex.Const.con->Ico.U16))));
+               break;
             case Iop_Mul32:
                e2 = IRExpr_Const(IRConst_U32(
                        (e->Iex.Binop.arg1->Iex.Const.con->Ico.U32
@@ -2078,6 +2088,53 @@ static IRExpr* fold_Expr_WRK ( IRExpr** env, IRExpr* e )
                         * e->Iex.Binop.arg2->Iex.Const.con->Ico.U64)));
                break;
 
+            case Iop_MullU8: {
+               UChar  u8a = e->Iex.Binop.arg1->Iex.Const.con->Ico.U8;
+               UChar  u8b = e->Iex.Binop.arg2->Iex.Const.con->Ico.U8;
+               Int    res = u8a * u8b;  /* Compiler will promote to int */
+               e2 = IRExpr_Const(IRConst_U16(toUShort(res)));
+               break;
+            }
+            case Iop_MullU16: {
+               UShort u16a = e->Iex.Binop.arg1->Iex.Const.con->Ico.U16;
+               UShort u16b = e->Iex.Binop.arg2->Iex.Const.con->Ico.U16;
+               Int    res = u16a * u16b;  /* Compiler will promote to int */
+               e2 = IRExpr_Const(IRConst_U32(res));
+               break;
+            }
+            case Iop_MullU32: {
+               UInt  u32a = e->Iex.Binop.arg1->Iex.Const.con->Ico.U32;
+               UInt  u32b = e->Iex.Binop.arg2->Iex.Const.con->Ico.U32;
+               ULong res = (ULong)u32a * (ULong)u32b;
+               e2 = IRExpr_Const(IRConst_U64(res));
+               break;
+            }
+            case Iop_MullS8: {
+               /* very paranoid */
+               UChar  u8a = e->Iex.Binop.arg1->Iex.Const.con->Ico.U8;
+               UChar  u8b = e->Iex.Binop.arg2->Iex.Const.con->Ico.U8;
+               Char   s8a = (Char)u8a;
+               Char   s8b = (Char)u8b;
+               Short  s16a = (Short)s8a;
+               Short  s16b = (Short)s8b;
+               Int    sres = s16a * s16b;
+               UShort ures = toUShort(sres);
+               e2 = IRExpr_Const(IRConst_U16(ures));
+               break;
+            }
+            case Iop_MullS16: {
+               /* very paranoid */
+               UShort u16a = e->Iex.Binop.arg1->Iex.Const.con->Ico.U16;
+               UShort u16b = e->Iex.Binop.arg2->Iex.Const.con->Ico.U16;
+               Short  s16a = (Short)u16a;
+               Short  s16b = (Short)u16b;
+               Int    s32a = (Int)s16a;
+               Int    s32b = (Int)s16b;
+               Int    sres = s32a * s32b;
+               UInt   ures = (UInt)sres;
+               e2 = IRExpr_Const(IRConst_U32(ures));
+               break;
+            }
             case Iop_MullS32: {
                /* very paranoid */
                UInt  u32a = e->Iex.Binop.arg1->Iex.Const.con->Ico.U32;
index 1ec2d77e3d09421c9c7126ea809dc2150d41c715..96e71a068e9c2a4cb226c17ae030ed824bc817dd 100644 (file)
@@ -144,6 +144,48 @@ check_result(const irop_t *op, const test_data_t *data)
       expected = opnd_l - opnd_r;
       break;
 
+   case Iop_Mul8:
+   case Iop_MullU8: {
+      uint8_t u8l = opnd_l;
+      uint8_t u8r = opnd_r;
+      expected = u8l * u8r;
+      break;
+   }
+   case Iop_Mul16:
+   case Iop_MullU16: {
+      uint16_t u16l = opnd_l;
+      uint16_t u16r = opnd_r;
+      expected = u16l * u16r;
+      break;
+   }
+   case Iop_Mul32:
+   case Iop_MullU32: {
+      uint32_t u32l = opnd_l;
+      uint32_t u32r = opnd_r;
+      expected = (uint64_t)u32l * (uint64_t)u32r;
+      break;
+   }
+
+   case Iop_Mul64:
+      expected = opnd_l * opnd_r;
+      break;
+
+   case Iop_MullS8: {
+      uint8_t u8l = opnd_l;
+      uint8_t u8r = opnd_r;
+      int8_t  s8l = (int8_t)u8l;
+      int8_t  s8r = (int8_t)u8r;
+      expected = (int16_t)s8l * (int16_t)s8r;
+      break;
+   }
+   case Iop_MullS16: {
+      uint16_t u16l = opnd_l;
+      uint16_t u16r = opnd_r;
+      int16_t  s16l = (int16_t)u16l;
+      int16_t  s16r = (int16_t)u16r;
+      expected = (int32_t)s16l * (int32_t)s16r;
+      break;
+   }
    case Iop_MullS32:
       expected = (int64_t)(int32_t)opnd_l * (int64_t)(int32_t)opnd_r;
       break;
index 68f8cc8860e82da777f6dd24f8e870988f91d212..5fb2016634c25064b703d327d55cf8a33ccfe78d 100644 (file)
    { OPNAME(Sub32),   Ity_I32, 2, Ity_I32, Ity_I32 },
    { OPNAME(Sub64),   Ity_I64, 2, Ity_I64, Ity_I64 },
 
-// { OPNAME(Mul8),    Ity_I8,  2, Ity_I8,  Ity_I8  },
-// { OPNAME(Mul16),   Ity_I16, 2, Ity_I16, Ity_I16 },
-// { OPNAME(Mul32),   Ity_I32, 2, Ity_I32, Ity_I32 },
-// { OPNAME(Mul64),   Ity_I64, 2, Ity_I64, Ity_I64 },
-
-// { OPNAME(MullU8),  Ity_I16,  2, Ity_I8,  Ity_I8  }, // no folding yet
-// { OPNAME(MullU16), Ity_I32,  2, Ity_I16, Ity_I16 }, // no folding yet
-// { OPNAME(MullU32), Ity_I64,  2, Ity_I32, Ity_I32 }, // no folding yet
+   { OPNAME(Mul8),    Ity_I8,  2, Ity_I8,  Ity_I8  },
+   { OPNAME(Mul16),   Ity_I16, 2, Ity_I16, Ity_I16 },
+   { OPNAME(Mul32),   Ity_I32, 2, Ity_I32, Ity_I32 },
+   { OPNAME(Mul64),   Ity_I64, 2, Ity_I64, Ity_I64 },
+
+   { OPNAME(MullU8),  Ity_I16,  2, Ity_I8,  Ity_I8  },
+   { OPNAME(MullU16), Ity_I32,  2, Ity_I16, Ity_I16 },
+   { OPNAME(MullU32), Ity_I64,  2, Ity_I32, Ity_I32 },
 // { OPNAME(MullU64), Ity_I128, 2, Ity_I64, Ity_I64 }, // 128 bit
 
-// { OPNAME(MullS8),  Ity_I16,  2, Ity_I8,  Ity_I8  }, // no folding yet
-// { OPNAME(MullS16), Ity_I32,  2, Ity_I16, Ity_I16 }, // no folding yet
+   { OPNAME(MullS8),  Ity_I16,  2, Ity_I8,  Ity_I8  },
+   { OPNAME(MullS16), Ity_I32,  2, Ity_I16, Ity_I16 },
    { OPNAME(MullS32), Ity_I64,  2, Ity_I32, Ity_I32 },
 // { OPNAME(MullS64), Ity_I128, 2, Ity_I64, Ity_I64 }, // 128 bit