Skip to content

Ensure rounding flag is properly emitted on some x86 floating point instructions#8015

Open
plafosse wants to merge 2 commits intodevfrom
test_x86_fp_flags
Open

Ensure rounding flag is properly emitted on some x86 floating point instructions#8015
plafosse wants to merge 2 commits intodevfrom
test_x86_fp_flags

Conversation

@plafosse
Copy link
Member

Summary

  • Add IL_FLAG_C1 as an explicit output to x87 intrinsics that use IL_FLAGWRITE_X87RND: F2XM1, FBLD, FSIN, FCOS, FSINCOS, FPATAN, FPTAN, FSCALE, FYL2X, FYL2XP1
  • Return il.Undefined() for C1 with IL_FLAGWRITE_X87RND — the rounding direction flag is runtime-dependent and can't be computed at lift time, so Undefined correctly invalidates prior values of C1 without claiming a false constant
  • Update intrinsic output type lists to include the additional bool output for the rounding flag

@rssor
Copy link
Member

rssor commented Mar 13, 2026

undefined we've mostly used as a block-ender top level instruction, letting it stay as unimplemented (which it is, because we can't really) might be fine? unless this is just to work around the fact that unavoidably adds low-value tags for unimplemented

undefined means (or at least used to) 'actual problem', and unimplemented was more 'benign/incalculable'

@rssor
Copy link
Member

rssor commented Mar 13, 2026

this is also why there's unimpl/unimpl_mem as well: they're meant for use as value-producing exprs that aren't actually harmful on their own. i wonder if we'd be better off just taking an instruction attribute bit to suppress tags so that it's safe for architectures to use unimplemented without adding tags every time we see one, since unimplemented is supposed to be safe to use. (or, stretch goal: suppress unimplemented tags by default since they aren't actionable for almost everybody who isn't working on an arch plugin)

as it is, we've kind of forced ourselves into running away from using the intended instruction because the tag makes it look like 'unimplemented' means 'haven't gotten to it yet' and not 'we need to clobber this with a stand-in expr, because there may not ever be anything sane to replace it with'. as it is, we're drifting towards repurposing another instruction just to get away from how we add tags (I think).

Adds Unknown() and UnknownMemoryRef() as first-class IL builder functions
(alongside Unimplemented/UnimplementedMemoryRef) that emit the same opcodes
with an unknown flag set. When the flag is set, the expression renders as
"unknown" instead of "unimplemented", indicating a genuinely unknowable
value rather than a missing lift. Suppresses the "Unimplemented Instruction"
auto-address tag.

IsUnknown() accessors on LLIL/MLIL/HLIL instruction types allow callers to
distinguish the two cases. Copy paths preserve the flag correctly.

The motivating case is the x87 C1 rounding flag (IL_FLAGWRITE_X87RND),
which is runtime-dependent and cannot be statically determined.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
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.

2 participants