Skip to content

DynComp: handle every unary VEX operation explicitly; add --dyncomp-unhandled-ops - #83

Closed
mernst wants to merge 2 commits into
codespecs:masterfrom
mernst:dyncomp-unop-cases
Closed

mernst wants to merge 2 commits into
codespecs:masterfrom
mernst:dyncomp-unop-cases

Conversation

@mernst

@mernst mernst commented Oct 10, 2026 •

Copy link
Copy Markdown
Member

expr2tags_Unop_DC used to ignore the operation: it returned the operand's tag for every unary operation, and its list of operations was only a comment. The binary, ternary, and quaternary functions instead switch on the operation and panic on one they do not handle. This pull request makes the arities consistent.

Unary operations are now handled explicitly. expr2tags_Unop_DC takes the operation and switches on it. All 283 unary operations in VEX/priv/ir_defs.c (typeOfPrimop) are covered:

  • 231 return the operand's tag, as before (widening, narrowing, reinterpreting, Not, Neg, conversions, ...).
  • 45 return tag 0 (see below).
  • 7 are listed as unimplemented (used only by ppc, arm64, or mips), like the "Unimplemented" cases of the other arities.

The comment list contained two binary operations (Iop_MulHi8Sx16, Iop_MulHi8Ux16); they are not unary cases.

Boolean, mask, and count results get tag 0. Binary comparisons merge their operands' tags and give the result tag 0, because the result is a boolean. The unary operations CmpNEZ*, CmpwNEZ*, 32to1, 64to1 (booleans or lane masks) and Clz*, Ctz*, PopCount*, GetMSBs* (counts or masks of the operand's bits) now do the same, instead of passing the operand's tag through. They do not simply return a constant tag 0, because then VEX would remove the operand's tag computation as dead code, together with any merge in it (such as the merge of a and b in char lt = (a < b)). Instead they pass the operand's tag to a new helper, MC_(helperc_RETURN_0), which returns 0.

New option --dyncomp-unhandled-ops=panic|warn. For every arity, an operation that DynComp does not handle reaches the default case, which calls report_unhandled_op_DC:

  • panic (the default) prints the operation and stops, as before.
  • warn prints a warning once per operation and approximates it: a unary operation returns its operand's tag; a binary operation merges its operands' tags (except in --dyncomp-interactions=comparisons mode); a ternary or quaternary operation merges all its operands' tags. Merging over-approximates comparability, which can hide no invariants.

The option is listed in --help, and ./check-options-documented passes. codespecs/daikon#891 documents it in the Daikon manual.

Testing: ./test-kvasir.sh (the DynComp and Kvasir regression tests) passes with no goal-file changes; make build (no new warnings); a small program using strlen, __builtin_ctz/clz/popcount, and comparisons produces .decls output identical to master's; --dyncomp-unhandled-ops=bogus is rejected.

expr2tags_Unop_DC now takes the operation and switches on it, like the
binary, ternary, and quaternary functions do.  Unary operations whose
result is a boolean, or a mask or count computed from the operand's bits
(CmpNEZ*, CmpwNEZ*, 32to1, 64to1, Clz*, Ctz*, PopCount*, GetMSBs*), give
the result tag 0, as binary comparisons do.  All other unary operations
return the tag of the operand, as before.  An operation that DynComp does
not handle now reaches the default case for every arity.

The new option --dyncomp-unhandled-ops=panic|warn controls what happens
then.  "panic" (the default) stops, as before.  "warn" prints a warning
once per operation and approximates the operation: a unary operation
returns its operand's tag, and other operations merge their operands'
tags.
@coderabbitai

coderabbitai Bot commented Oct 10, 2026 •

Copy link
Copy Markdown

Warning

Review limit reached

  • Run on-demand review

This review includes 5 billable files and costs up to $1.25.

Or wait 35 minutes for your next included review.

Check out review usage here.

View limit details

Limit details: You’ve used the included review currently available.

Learn how review limits work.

Review configuration:

⚙️ Run configuration
  • Configuration used: Repository: codespecs/fjalar/.coderabbit.yaml
  • Review profile: ASSERTIVE
  • Plan: Advanced
  • Run ID: ee89f4a9-35ac-4897-8792-765edacf563c

📥 Commits

Reviewing files that changed from the base of the PR and between ea8fa94 and 737b1bc.


📒 Files selected for processing (5)
  • valgrind/fjalar/kvasir/dyncomp_main.c
  • valgrind/fjalar/kvasir/dyncomp_main.h
  • valgrind/fjalar/kvasir/dyncomp_translate.c
  • valgrind/fjalar/kvasir/kvasir_main.c
  • valgrind/fjalar/kvasir/kvasir_main.h

  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Comment @coderabbitai help to get the list of available commands.

… gets tag 0

Returning a constant tag discarded the operand's tag expression, so VEX
removed it as dead code, along with any merge it performed.  For
example, in 'char lt = (a < b)' the merge of a and b was lost.
@mernst

mernst commented Oct 10, 2026

Copy link
Copy Markdown
Member Author

Superseded by #85, #86, and #87, which split this pull request into three parts. Together they have the same final tree as this pull request.

@mernst mernst closed this Oct 10, 2026
@mernst
mernst deleted the dyncomp-unop-cases branch October 10, 2026 18:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant