-
Notifications
You must be signed in to change notification settings - Fork 1.4k
Make use of Unary opcodes
#6647
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 1 commit
eece3bf
fd3ef1d
c54b881
15d9e0a
5641bc9
cf8cf21
f12d2f3
50763ce
0696124
f86f0d5
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
- Loading branch information
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -5,7 +5,7 @@ use cranelift::prelude::*; | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| use num_traits::cast::ToPrimitive; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| use rustpython_compiler_core::bytecode::{ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| self, BinaryOperator, BorrowedConstant, CodeObject, ComparisonOperator, Instruction, Label, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| OpArg, OpArgState, UnaryOperator, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| OpArg, OpArgState, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| use std::collections::HashMap; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -620,28 +620,22 @@ impl<'a, 'b> FunctionCompiler<'a, 'b> { | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| self.stack.swap(i, j); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Ok(()) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Instruction::UnaryOperation { op, .. } => { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| let op = op.get(arg); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Instruction::UnaryNot => { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| let a = self.stack.pop().ok_or(JitCompileError::BadBytecode)?; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| match (op, a) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| (UnaryOperator::Minus, JitValue::Int(val)) => { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // Compile minus as 0 - a. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| let boolean = self.boolean_val(a)?; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| let not_boolean = self.builder.ins().bxor_imm(boolean, 1); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| self.stack.push(JitValue::Bool(not_boolean)); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Ok(()) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Instruction::UnaryInvert => { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| match self.stack.pop().ok_or(JitCompileError::BadBytecode)? { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| JitValue::Int(val) => { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // Compile minus as 0 - val. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| let zero = self.builder.ins().iconst(types::I64, 0); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| let out = self.compile_sub(zero, val); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| self.stack.push(JitValue::Int(out)); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Ok(()) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| (UnaryOperator::Plus, JitValue::Int(val)) => { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // Nothing to do | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| self.stack.push(JitValue::Int(val)); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Ok(()) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| (UnaryOperator::Not, a) => { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| let boolean = self.boolean_val(a)?; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| let not_boolean = self.builder.ins().bxor_imm(boolean, 1); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| self.stack.push(JitValue::Bool(not_boolean)); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Ok(()) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| _ => Err(JitCompileError::NotSupported), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Critical: Incorrect implementation of bitwise invert operator. The Examples of the bug:
🔎 Proposed fix for bitwise invert Instruction::UnaryInvert => {
match self.stack.pop().ok_or(JitCompileError::BadBytecode)? {
JitValue::Int(val) => {
- // Compile minus as 0 - val.
+ // Bitwise invert: ~x = -x - 1
let zero = self.builder.ins().iconst(types::I64, 0);
- let out = self.compile_sub(zero, val);
+ let neg_val = self.compile_sub(zero, val);
+ let one = self.builder.ins().iconst(types::I64, 1);
+ let out = self.compile_sub(neg_val, one);
self.stack.push(JitValue::Int(out));
Ok(())
}
_ => Err(JitCompileError::NotSupported),
}
}Alternatively, if Cranelift supports bitwise NOT directly (e.g., Instruction::UnaryInvert => {
match self.stack.pop().ok_or(JitCompileError::BadBytecode)? {
JitValue::Int(val) => {
- // Compile minus as 0 - val.
- let zero = self.builder.ins().iconst(types::I64, 0);
- let out = self.compile_sub(zero, val);
+ // Bitwise invert using NOT instruction
+ let out = self.builder.ins().bnot(val);
self.stack.push(JitValue::Int(out));
Ok(())
}
_ => Err(JitCompileError::NotSupported),
}
}📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents
Comment on lines
+653
to
664
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧩 Analysis chain🏁 Script executed: #!/bin/bash
# Search for fneg and Float handling in unary operations
rg -nP --type=rust -C3 'fneg|UnaryNegative.*Float|Float.*UnaryNegative' crates/jit/src/Repository: RustPython/RustPython Length of output: 609 🏁 Script executed: #!/bin/bash
# Check the full context around UnaryNegative and look for Float handling patterns
rg -nP --type=rust -B5 -A10 'Instruction::UnaryNegative' crates/jit/src/Repository: RustPython/RustPython Length of output: 1435 🏁 Script executed: #!/bin/bash
# Search for UnaryPositive to see if it has similar patterns
rg -nP --type=rust -B2 -A8 'Instruction::UnaryPositive' crates/jit/src/Repository: RustPython/RustPython Length of output: 47 🏁 Script executed: #!/bin/bash
# Look for Float handling in other unary or binary operations for reference
rg -nP --type=rust 'JitValue::Float.*=>' crates/jit/src/ | head -20Repository: RustPython/RustPython Length of output: 556 Add Float support to UnaryNegative handler. The implementation handles JitValue::Float(val) => {
let out = self.builder.ins().fneg(val);
self.stack.push(JitValue::Float(out));
Ok(())
}🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Uh oh!
There was an error while loading. Please reload this page.