]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
Fix Iop_ClzNat32/64 and Iop_CtzNat32/64 on x86 and amd64.
authorFlorian Krohm <flo2030@eich-krohm.de>
Tue, 26 Aug 2025 20:52:26 +0000 (20:52 +0000)
committerFlorian Krohm <flo2030@eich-krohm.de>
Tue, 26 Aug 2025 20:52:26 +0000 (20:52 +0000)
Handle the special case of 0 operand.

Fixes https://bugs.kde.org/show_bug.cgi?id=507033

VEX/priv/host_amd64_isel.c
VEX/priv/host_x86_isel.c

index f0e21ab9831f8b87514933bf0d6bad7cb613bfef..113dc1bf3c08f515b40e3d4365cb18342f35bc4d 100644 (file)
@@ -1633,6 +1633,11 @@ static HReg iselIntExpr_R_wrk ( ISelEnv* env, const IRExpr* e )
             HReg dst = newVRegI(env);
             HReg src = iselIntExpr_R(env, e->Iex.Unop.arg);
             addInstr(env, AMD64Instr_Bsfr64(True,src,dst));
+            /* Patch the result in case there was a 0 operand. */
+            IRExpr *cond = unop(Iop_CmpNEZ64, e->Iex.Unop.arg);
+            AMD64CondCode cc = iselCondCode_C(env, cond);
+            HReg ifz = iselIntExpr_R(env, IRExpr_Const(IRConst_U64(64)));
+            addInstr(env, AMD64Instr_CMov64(cc ^ 1, ifz, dst));
             return dst;
          }
          case Iop_ClzNat64: {
@@ -1647,6 +1652,11 @@ static HReg iselIntExpr_R_wrk ( ISelEnv* env, const IRExpr* e )
                                             AMD64RMI_Imm(63), dst));
             addInstr(env, AMD64Instr_Alu64R(Aalu_SUB,
                                             AMD64RMI_Reg(tmp), dst));
+            /* Patch the result in case there was a 0 operand. */
+            IRExpr *cond = unop(Iop_CmpNEZ64, e->Iex.Unop.arg);
+            AMD64CondCode cc = iselCondCode_C(env, cond);
+            HReg ifz = iselIntExpr_R(env, IRExpr_Const(IRConst_U64(64)));
+            addInstr(env, AMD64Instr_CMov64(cc ^ 1, ifz, dst));
             return dst;
          }
 
index d35df8fc4755e0540660224c51b02a54d7b6e627..b80d1116afc5255b57379eab0f693295a7befd77 100644 (file)
@@ -1311,6 +1311,11 @@ static HReg iselIntExpr_R_wrk ( ISelEnv* env, const IRExpr* e )
             HReg dst = newVRegI(env);
             HReg src = iselIntExpr_R(env, e->Iex.Unop.arg);
             addInstr(env, X86Instr_Bsfr32(True,src,dst));
+            /* Patch the result in case there was a 0 operand. */
+            IRExpr *cond = unop(Iop_CmpNEZ32, e->Iex.Unop.arg);
+            X86CondCode cc = iselCondCode(env, cond);
+            X86RM *ifz = iselIntExpr_RM(env, IRExpr_Const(IRConst_U32(32)));
+            addInstr(env, X86Instr_CMov32(cc ^ 1, ifz, dst));
             return dst;
          }
          case Iop_ClzNat32: {
@@ -1325,6 +1330,11 @@ static HReg iselIntExpr_R_wrk ( ISelEnv* env, const IRExpr* e )
                                           X86RMI_Imm(31), dst));
             addInstr(env, X86Instr_Alu32R(Xalu_SUB,
                                           X86RMI_Reg(tmp), dst));
+            /* Patch the result in case there was a 0 operand. */
+            IRExpr *cond = unop(Iop_CmpNEZ32, e->Iex.Unop.arg);
+            X86CondCode cc = iselCondCode(env, cond);
+            X86RM *ifz = iselIntExpr_RM(env, IRExpr_Const(IRConst_U32(32)));
+            addInstr(env, X86Instr_CMov32(cc ^ 1, ifz, dst));
             return dst;
          }