Skip to content

Commit

Permalink
Fix some small issues in compiling load and store IR instructions whe…
Browse files Browse the repository at this point in the history
…n the word offset is > 4096 (#2252)

* Fixing a small issue in compiling load instructions

* Add tests
  • Loading branch information
mohammadfawaz authored Jul 8, 2022
1 parent 2a42019 commit fcd6927
Show file tree
Hide file tree
Showing 3 changed files with 181 additions and 136 deletions.
15 changes: 10 additions & 5 deletions sway-core/src/asm_generation/from_ir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1403,19 +1403,24 @@ impl<'ir> AsmBuilder<'ir> {
// Value can fit in a register, so we load the value.
if word_offs > compiler_constants::TWELVE_BITS {
let offs_reg = self.reg_seqr.next();
self.number_to_reg(
word_offs * 8, // Base reg for LW is in bytes
&offs_reg,
instr_val.get_span(self.context),
);
self.bytecode.push(Op {
opcode: Either::Left(VirtualOp::ADD(
base_reg.clone(),
offs_reg.clone(),
base_reg,
offs_reg.clone(),
)),
comment: "insert_value absolute offset".into(),
comment: "absolute offset for load".into(),
owning_span: instr_val.get_span(self.context),
});
self.bytecode.push(Op {
opcode: Either::Left(VirtualOp::LW(
instr_reg.clone(),
offs_reg,
offs_reg.clone(),
VirtualImmediate12 { value: 0 },
)),
comment: "load value".into(),
Expand Down Expand Up @@ -1784,13 +1789,13 @@ impl<'ir> AsmBuilder<'ir> {
if word_offs > compiler_constants::TWELVE_BITS {
let offs_reg = self.reg_seqr.next();
self.number_to_reg(
word_offs,
word_offs * 8, // Base reg for SW is in bytes
&offs_reg,
instr_val.get_span(self.context),
);
self.bytecode.push(Op {
opcode: Either::Left(VirtualOp::ADD(
base_reg.clone(),
offs_reg.clone(),
base_reg,
offs_reg.clone(),
)),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,142 +10,182 @@ struct Z {
}

fn main() -> u64 {
// Chosen name forces this variable to show up last in the list of locals in IR
// Chosen names force these variables to show up last in the list of locals in IR so they will
// be allocated last and require the highest offset to be computed

// Test get_ptr large offset
let zzz = Z {
a: 1,
b: 2,
c: 3,
d: 4,
};

// Add enough stack variables to reach > 4096 bytes
let b = ZERO_B256;
let b = ZERO_B256;
let b = ZERO_B256;
let b = ZERO_B256;
let b = ZERO_B256;
let b = ZERO_B256;
let b = ZERO_B256;
let b = ZERO_B256;
let b = ZERO_B256;
let b = ZERO_B256;
let b = ZERO_B256;
let b = ZERO_B256;
let b = ZERO_B256;
let b = ZERO_B256;
let b = ZERO_B256;
let b = ZERO_B256;
let b = ZERO_B256;
let b = ZERO_B256;
let b = ZERO_B256;
let b = ZERO_B256;
let b = ZERO_B256;
let b = ZERO_B256;
let b = ZERO_B256;
let b = ZERO_B256;
let b = ZERO_B256;
let b = ZERO_B256;
let b = ZERO_B256;
let b = ZERO_B256;
let b = ZERO_B256;
let b = ZERO_B256;
let b = ZERO_B256;
let b = ZERO_B256;
let b = ZERO_B256;
let b = ZERO_B256;
let b = ZERO_B256;
let b = ZERO_B256;
let b = ZERO_B256;
let b = ZERO_B256;
let b = ZERO_B256;
let b = ZERO_B256;
let b = ZERO_B256;
let b = ZERO_B256;
let b = ZERO_B256;
let b = ZERO_B256;
let b = ZERO_B256;
let b = ZERO_B256;
let b = ZERO_B256;
let b = ZERO_B256;
let b = ZERO_B256;
let b = ZERO_B256;
let b = ZERO_B256;
let b = ZERO_B256;
let b = ZERO_B256;
let b = ZERO_B256;
let b = ZERO_B256;
let b = ZERO_B256;
let b = ZERO_B256;
let b = ZERO_B256;
let b = ZERO_B256;
let b = ZERO_B256;
let b = ZERO_B256;
let b = ZERO_B256;
let b = ZERO_B256;
let b = ZERO_B256;
let b = ZERO_B256;
let b = ZERO_B256;
let b = ZERO_B256;
let b = ZERO_B256;
let b = ZERO_B256;
let b = ZERO_B256;
let b = ZERO_B256;
let b = ZERO_B256;
let b = ZERO_B256;
let b = ZERO_B256;
let b = ZERO_B256;
let b = ZERO_B256;
let b = ZERO_B256;
let b = ZERO_B256;
let b = ZERO_B256;
let b = ZERO_B256;
let b = ZERO_B256;
let b = ZERO_B256;
let b = ZERO_B256;
let b = ZERO_B256;
let b = ZERO_B256;
let b = ZERO_B256;
let b = ZERO_B256;
let b = ZERO_B256;
let b = ZERO_B256;
let b = ZERO_B256;
let b = ZERO_B256;
let b = ZERO_B256;
let b = ZERO_B256;
let b = ZERO_B256;
let b = ZERO_B256;
let b = ZERO_B256;
let b = ZERO_B256;
let b = ZERO_B256;
let b = ZERO_B256;
let b = ZERO_B256;
let b = ZERO_B256;
let b = ZERO_B256;
let b = ZERO_B256;
let b = ZERO_B256;
let b = ZERO_B256;
let b = ZERO_B256;
let b = ZERO_B256;
let b = ZERO_B256;
let b = ZERO_B256;
let b = ZERO_B256;
let b = ZERO_B256;
let b = ZERO_B256;
let b = ZERO_B256;
let b = ZERO_B256;
let b = ZERO_B256;
let b = ZERO_B256;
let b = ZERO_B256;
let b = ZERO_B256;
let b = ZERO_B256;
let b = ZERO_B256;
let b = ZERO_B256;
let b = ZERO_B256;
let b = ZERO_B256;
let b = ZERO_B256;
let b = ZERO_B256;
let b = ZERO_B256;
let b = ZERO_B256;
// Test LW/SW with large offsets
let z1 = 5;
let z2 = 6;

// Add enough stack variables to reach > 4096 words
foo();
foo();
foo();
foo();
foo();
foo();
foo();
foo();
foo();
foo();
foo();
foo();
foo();
foo();
foo();
foo();
foo();
foo();
foo();
foo();
foo();
foo();
foo();
foo();
foo();
foo();
foo();
foo();
foo();
foo();
foo();
foo();
foo();
foo();

return zzz.a + zzz.b + zzz.c + zzz.d + z1 + z2 // get 16
}

return zzz.a + zzz.b + zzz.c + zzz.d
fn foo() {
let c = 0;
let c = 0;
let c = 0;
let c = 0;
let c = 0;
let c = 0;
let c = 0;
let c = 0;
let c = 0;
let c = 0;
let c = 0;
let c = 0;
let c = 0;
let c = 0;
let c = 0;
let c = 0;
let c = 0;
let c = 0;
let c = 0;
let c = 0;
let c = 0;
let c = 0;
let c = 0;
let c = 0;
let c = 0;
let c = 0;
let c = 0;
let c = 0;
let c = 0;
let c = 0;
let c = 0;
let c = 0;
let c = 0;
let c = 0;
let c = 0;
let c = 0;
let c = 0;
let c = 0;
let c = 0;
let c = 0;
let c = 0;
let c = 0;
let c = 0;
let c = 0;
let c = 0;
let c = 0;
let c = 0;
let c = 0;
let c = 0;
let c = 0;
let c = 0;
let c = 0;
let c = 0;
let c = 0;
let c = 0;
let c = 0;
let c = 0;
let c = 0;
let c = 0;
let c = 0;
let c = 0;
let c = 0;
let c = 0;
let c = 0;
let c = 0;
let c = 0;
let c = 0;
let c = 0;
let c = 0;
let c = 0;
let c = 0;
let c = 0;
let c = 0;
let c = 0;
let c = 0;
let c = 0;
let c = 0;
let c = 0;
let c = 0;
let c = 0;
let c = 0;
let c = 0;
let c = 0;
let c = 0;
let c = 0;
let c = 0;
let c = 0;
let c = 0;
let c = 0;
let c = 0;
let c = 0;
let c = 0;
let c = 0;
let c = 0;
let c = 0;
let c = 0;
let c = 0;
let c = 0;
let c = 0;
let c = 0;
let c = 0;
let c = 0;
let c = 0;
let c = 0;
let c = 0;
let c = 0;
let c = 0;
let c = 0;
let c = 0;
let c = 0;
let c = 0;
let c = 0;
let c = 0;
let c = 0;
let c = 0;
let c = 0;
let c = 0;
let c = 0;
let c = 0;
let c = 0;
let c = 0;
let c = 0;
let c = 0;
}
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
category = "run"
expected_result = { action = "return", value = 10 }
expected_result = { action = "return", value = 21 }
validate_abi = true

0 comments on commit fcd6927

Please sign in to comment.