Bug 381713

Summary: optimize CmpNEx(a, 0) as CmpNEZx(a) in VEX IR
Product: [Developer tools] valgrind Reporter: Ivo Raisr <ivosh>
Component: vexAssignee: Ivo Raisr <ivosh>
Status: RESOLVED INTENTIONAL    
Severity: minor CC: jseward
Priority: NOR    
Version First Reported In: 3.14 SVN   
Target Milestone: ---   
Platform: Compiled Sources   
OS: Linux   
Latest Commit: Version Fixed/Implemented In:
Sentry Crash Report:

Description Ivo Raisr 2017-06-27 07:36:56 UTC
VEX IR optimizer should optimize CmpNEx(a, 0) as CmpNEZx(a).

CmpNEx(a, 0) is typically produced by VEX frontends for emulation warnings.
For example in guest_x86_toIR.c:

4110                 /* Finally, if an emulation warning was reported,
4111                    side-exit to the next insn, reporting the warning,
4112                    so that Valgrind's dispatcher sees the warning. */
4113                 stmt(
4114                    IRStmt_Exit(
4115                       binop(Iop_CmpNE32, mkexpr(ew), mkU32(0)),
4116                       Ijk_EmWarn,
4117                       IRConst_U32( ((Addr32)guest_EIP_bbstart)+delta),
4118                       OFFB_EIP
4119                    )
4120                 );
Comment 1 Julian Seward 2017-06-27 09:19:11 UTC
(In reply to Ivo Raisr from comment #0)
> VEX IR optimizer should optimize CmpNEx(a, 0) as CmpNEZx(a).

You can do that, sure, but then you will have to teach the Memcheck
instrumenter how to instrument CmpNEZx (which is no big deal).  The reason
for the current arrangement is that the front ends produce (eg) CmpNE32,
but no CmpNEZx.  But the Memcheck instrumenter produces CmpNE(..., 0) so
often (it is the "is any part of this undefined?" question) that I thought
it better to have a special case.

I think the back ends do (or should!) have various special cases to handle
these situations well.  For example, CmpNE32(Or32(x,y), 0) can be done on
x86/amd64 just by doing an OR instruction and then branching on the NZ
condition.  No need for an actual compare.