Skip to content

sroa is generating invalid IR #7433

@xunilrj

Description

@xunilrj

This can be reproduced on master with the following command:

> cargo r -p forc --release -- build --path test/src/e2e_vm_tests/test_programs/should_pass/language/main_args/main_args_various_types --release --ir final

I don't know how but this compiles fine; by doing a small change to allow the IR to be verified between passes, it panics on the sroa pass.

for pass in passes.flatten_pass_group() {
    ir.verify2().unwrap();

    let modified_in_pass = self.actually_run(ir, pass)?;

    if print_opts.passes.contains(pass) && (!print_opts.modified_only || modified_in_pass) {
        print_ir_after_pass(ir, self.lookup_registered_pass(pass).unwrap());
    }

    modified |= modified_in_pass;

    if ir.verify2().is_err() {
        panic!("{pass} generated invalid IR");
    }
}

The only difference for verify2 is to support &mut self:

pub fn verify2(&mut self) -> Result<(), IrError> {
    for (module, _) in &self.modules {
        let module = Module(module);
        self.verify_module(module)?;
    }
    Ok(())
}

The problem seems to be that some get_elem_ptr endup with empty indices.

Verification failed at as_raw_slice_28::entry
v41 = load v40
v42 = get_elem_ptr v39, __ptr u64,                              <-------- look here
store v41 to v42
v43 = asm(s: v32) -> __ptr slice s {
}

The error on the final IR is:

pub fn as_raw_slice_28(self: __ptr { { ptr, u64, u64 } }, __ret_value: __ptr slice) -> (), !452 {
    local mut slice __aggr_memcpy_00
    local { ptr, u64 } __anon_1
    local { { ptr, u64, u64 } } self_

    entry(self: __ptr { { ptr, u64, u64 } }, __ret_value: __ptr slice):
    v0 = get_local __ptr { { ptr, u64, u64 } }, self_
    mem_copy_val v0, self
    v1 = get_local __ptr { { ptr, u64, u64 } }, self_, !453
    v2 = const u64 0
    v3 = get_elem_ptr v1, __ptr { ptr, u64, u64 }, v2, !249
    v4 = asm(buffer: v3) -> __ptr { ptr, u64, u64 } buffer {
    }
    v5 = const u64 0
    v6 = get_elem_ptr v4, __ptr ptr, v5
    v7 = load v6
    v8 = const u64 2
    v9 = get_elem_ptr v4, __ptr u64, v8
    v10 = load v9
    v11 = get_local __ptr { ptr, u64 }, __anon_1
    v12 = const u64 0
    v13 = get_elem_ptr v11, __ptr ptr, v12
    v14 = get_elem_ptr v13, __ptr ptr, 
    store v7 to v14
    v15 = const u64 1
    v16 = get_elem_ptr v11, __ptr u64, v15
    v17 = get_elem_ptr v16, __ptr u64, 
    store v10 to v17
    v18 = asm(s: v11) -> __ptr slice s {
    }
    v19 = get_local __ptr slice, __aggr_memcpy_00
    mem_copy_val v19, v18
    mem_copy_val __ret_value, v19
    v20 = const unit ()
    ret () v20
}

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions