Conversation
`trunc_local` only accepted operand and result widths in {8, 16, 32, 64},
so any `trunc` to `i1` (which `legalize` emits when it widens an `i1`
arithmetic op) survived instruction selection. Accept every operand width
up to 64 instead.
The lowering stays a pair of casts: the result's upper register bits are
whatever the operand left there, and `reconcile-cast` zero-extends the
value wherever it is used as a register again, which is the convention
all the isel proofs assume (`LLVM.Int.toReg` zero-extends). The psABI
only constrains values at function boundaries, which this does not touch.
The six per-width `trunc_refinement_*` theorems are replaced by one,
`trunc_refinement_le64`, covering every `w₂ < w₁ ≤ 64`.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
trunc_localonly accepted operand and result widths in {8, 16, 32, 64}, so anytrunctoi1survived RISC-V instruction selection.legalizeemits these itself when it widens ani1add/sub/mul/and/or/xor toi64. In a census of 500 programs fromvsmith --riscv, 458 had a leftovertrunc … -> i1.This PR accepts every operand width up to 64 (including odd ones like
i52 -> i3). Operands wider than 64 bits are still left alone.Why it's sound: the lowering is still just a pair of casts through
!riscv.reg. The result's upper register bits are whatever the operand left there, andreconcile-castzero-extends the value wherever it is used as a register again (slli/srlifori1). That matches the convention all the isel proofs assume, sinceLLVM.Int.toRegzero-extends. The RISC-V psABI only constrains how narrow integers are extended at function boundaries, which this doesn't touch.Proof: the six per-width
trunc_refinement_*theorems are replaced by a singletrunc_refinement_le64, which covers everyw₂ < w₁ ≤ 64, including thensw/nuwpoison cases. It usespbv_decide.Tests:
trunc.mlirgainsi64 -> i1andi52 -> i3cases, plus a check thati65 -> i1is not lowered.trunc_i1_exec.mlir:trunc 6 -> i1is false even though the register still holds 6, and thei1feeds both aselectand acond_br. It runs the fullriscvpipeline and checks that the lowered program returns the same value as the source.🤖 Generated with Claude Code