Skip to content

Commit

Permalink
[asmgen] pushing / popping registers for call should handle all def'd…
Browse files Browse the repository at this point in the history
… regs (#6826)

Fixes #6814
  • Loading branch information
vaivaswatha authored Jan 18, 2025
1 parent 9cd1b39 commit a67e9a9
Show file tree
Hide file tree
Showing 5 changed files with 86 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -78,21 +78,21 @@ impl AllocatedAbstractInstructionSet {
.fold(
(IndexMap::new(), IndexSet::new()),
|(mut reg_sets, mut active_sets), op| {
let reg = match &op.opcode {
let regs: Box<dyn Iterator<Item = &AllocatedRegister>> = match &op.opcode {
Either::Right(ControlFlowOp::PushAll(label)) => {
active_sets.insert(*label);
None
Box::new(std::iter::empty())
}
Either::Right(ControlFlowOp::PopAll(label)) => {
active_sets.swap_remove(label);
None
Box::new(std::iter::empty())
}

Either::Left(alloc_op) => alloc_op.def_registers().into_iter().next(),
Either::Right(ctrl_op) => ctrl_op.def_registers().into_iter().next(),
Either::Left(alloc_op) => Box::new(alloc_op.def_registers().into_iter()),
Either::Right(ctrl_op) => Box::new(ctrl_op.def_registers().into_iter()),
};

if let Some(reg) = reg {
for reg in regs {
for active_label in active_sets.clone() {
reg_sets
.entry(active_label)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
[[package]]
name = "core"
source = "path+from-root-B299C98691745B40"

[[package]]
name = "pusha_popa_multiple_defreg"
source = "member"
dependencies = ["std"]

[[package]]
name = "std"
source = "path+from-root-B299C98691745B40"
dependencies = ["core"]
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
[project]
authors = ["Fuel Labs <[email protected]>"]
entry = "main.sw"
license = "Apache-2.0"
name = "pusha_popa_multiple_defreg"

[dependencies]
std = { path = "../../../../reduced_std_libs/sway-lib-std-assert" }
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
contract;

abi IncorrectPushaPopa {
#[storage(read)]
fn incorrect_pusha_popa() -> ();
}

impl IncorrectPushaPopa for Contract {
#[storage(read)]
fn incorrect_pusha_popa() -> () {
setup();
()
}
}

#[storage(read)]
fn setup() -> () {
let a: u64 = 1;
let b: u64 = 1;
let c: u64 = 1;
//call a few times to avoid inline
store_read();
let r = asm(r, a: a, b: b, c: c, d: store_read()) {
movi r i0;
add r a b; // r = a + b = 2
add r r c; // r = a + b + c = 3 c value is overwritten by store_read, so we get 2 instead
add r r d; // r = a + b + c + d = 3 d returns 0
r
};
assert(r == 3);
()
}

#[storage(read)]
fn store_read() -> u64 {
let a = asm(slot, a, b, c) {
movi c i32;
aloc c;
move slot hp;
srw a b slot; // somehow make b allocate to $r3
movi c i0;
add a a slot;
sub a a slot;
add a a b;
add a a c;
a
};
a - a // return 0 and make sure a is not dced
}

#[test]
fn incorrect_pusha_popa() -> () {
let c = abi(IncorrectPushaPopa, CONTRACT_ID);
c.incorrect_pusha_popa();
()
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
category = "unit_tests_pass"
validate_abi = false
expected_warnings = 0

0 comments on commit a67e9a9

Please sign in to comment.