diff --git a/lang/README.md b/lang/README.md index c72472ae..88b61841 100644 --- a/lang/README.md +++ b/lang/README.md @@ -1465,6 +1465,19 @@ main := fn(): uint { } ``` +#### global_variable_wiredness +```hb +ports := false + +inb := fn(): uint return 0 + +main := fn(): void { + if ports { + ports = inb() == 0x0 + } +} +``` + ### Just Testing Optimizations #### null_check_test diff --git a/lang/src/son.rs b/lang/src/son.rs index 87b03c66..b5fcd999 100644 --- a/lang/src/son.rs +++ b/lang/src/son.rs @@ -4874,6 +4874,7 @@ mod tests { writing_into_string; request_page; tests_ptr_to_ptr_copy; + global_variable_wiredness; // Just Testing Optimizations; const_folding_with_arg; diff --git a/lang/src/son/hbvm.rs b/lang/src/son/hbvm.rs index 399b2bf3..24c594a0 100644 --- a/lang/src/son/hbvm.rs +++ b/lang/src/son/hbvm.rs @@ -236,7 +236,12 @@ impl Backend for HbvmBackend { if !matches!(nodes[stck].kind, Kind::Stck | Kind::Arg) { debug_assert_matches!( nodes[stck].kind, - Kind::Phi | Kind::Return | Kind::Load | Kind::Call { .. } | Kind::Stre + Kind::Phi + | Kind::Return + | Kind::Load + | Kind::Call { .. } + | Kind::Stre + | Kind::Join ); continue; } @@ -334,40 +339,18 @@ impl Backend for HbvmBackend { impl Nodes { fn reschedule_block(&mut self, from: Nid, outputs: &mut Vc) { // NOTE: this code is horible - let from = Some(&from); + let fromc = Some(&from); let mut buf = Vec::with_capacity(outputs.len()); let mut seen = BitSet::default(); seen.clear(self.values.len()); for &o in outputs.iter() { - if !self.is_cfg(o) { - continue; - } - - seen.set(o); - - let mut cursor = buf.len(); - buf.push(o); - while let Some(&n) = buf.get(cursor) { - for &i in &self[n].inputs[1..] { - if from == self[i].inputs.first() - && self[i] - .outputs - .iter() - .all(|&o| self[o].inputs.first() != from || seen.get(o)) - && seen.set(i) - { - for &o in outputs.iter().filter(|&&n| n == i) { - buf.push(o); - } - } - } - cursor += 1; - } - } - - for &o in outputs.iter() { - if !seen.set(o) { + if (!self.is_cfg(o) + && self[o].outputs.iter().any(|&oi| { + self[oi].kind != Kind::Phi && self[oi].inputs.first() == fromc && !seen.get(oi) + })) + || !seen.set(o) + { continue; } let mut cursor = buf.len(); @@ -376,11 +359,12 @@ impl Nodes { } while let Some(&n) = buf.get(cursor) { for &i in &self[n].inputs[1..] { - if from == self[i].inputs.first() - && self[i] - .outputs - .iter() - .all(|&o| self[o].inputs.first() != from || seen.get(o)) + if fromc == self[i].inputs.first() + && self[i].outputs.iter().all(|&o| { + self[o].kind == Kind::Phi + || self[o].inputs.first() != fromc + || seen.get(o) + }) && seen.set(i) { for &o in outputs.iter().filter(|&&n| n == i) { @@ -392,7 +376,18 @@ impl Nodes { } } - buf.sort_by_key(|&n| !self.is_cfg(n)); + debug_assert_eq!( + outputs.iter().filter(|&&n| !seen.get(n)).copied().collect::>(), + vec![], + "{:?} {from:?} {:?}", + outputs + .iter() + .filter(|&&n| !seen.get(n)) + .copied() + .map(|n| (n, &self[n])) + .collect::>(), + self[from] + ); if outputs.len() != buf.len() { panic!("{:?} {:?}", outputs, buf); diff --git a/lang/tests/son_tests_global_variable_wiredness.txt b/lang/tests/son_tests_global_variable_wiredness.txt new file mode 100644 index 00000000..448d583f --- /dev/null +++ b/lang/tests/son_tests_global_variable_wiredness.txt @@ -0,0 +1,23 @@ +inb: + LI64 r1, 0d + JALA r0, r31, 0a +main: + ADDI64 r254, r254, -40d + ST r31, r254, 0a, 40h + LRA r32, r0, :ports + LD r33, r32, 0a, 1h + ANDI r33, r33, 255d + JNE r33, r0, :0 + JMP :1 + 0: JAL r31, r0, :inb + LI64 r34, 0d + CMPU r35, r1, r34 + CMPUI r35, r35, 0d + NOT r35, r35 + ST r35, r32, 0a, 1h + 1: LD r31, r254, 0a, 40h + ADDI64 r254, r254, 40d + JALA r0, r31, 0a +code size: 178 +ret: 0 +status: Ok(()) diff --git a/lang/tests/son_tests_storing_into_nullable_struct.txt b/lang/tests/son_tests_storing_into_nullable_struct.txt index f007bfea..d0cc4854 100644 --- a/lang/tests/son_tests_storing_into_nullable_struct.txt +++ b/lang/tests/son_tests_storing_into_nullable_struct.txt @@ -50,18 +50,20 @@ optional: JALA r0, r31, 0a optionala: ADDI64 r254, r254, -48d - ADDI64 r5, r254, 0d + ADDI64 r5, r254, 8d ADDI64 r4, r254, 16d ST r5, r254, 16a, 8h LI64 r9, 1d ST r9, r254, 24a, 8h - ADDI64 r12, r254, 8d + ADDI64 r12, r254, 0d ST r12, r254, 32a, 8h LI64 r11, 0d + ST r11, r254, 0a, 8h + ST r11, r254, 8a, 8h ST r11, r254, 40a, 8h BMC r4, r1, 32h ADDI64 r254, r254, 48d JALA r0, r31, 0a -code size: 577 +code size: 603 ret: 100 status: Ok(()) diff --git a/lang/tests/son_tests_triggering_store_in_divergent_branch.txt b/lang/tests/son_tests_triggering_store_in_divergent_branch.txt index e69de29b..28f60765 100644 --- a/lang/tests/son_tests_triggering_store_in_divergent_branch.txt +++ b/lang/tests/son_tests_triggering_store_in_divergent_branch.txt @@ -0,0 +1,35 @@ +main: + ADDI64 r254, r254, -72d + ST r31, r254, 0a, 72h + LI8 r32, 0b + LI64 r33, 65536d + LI8 r34, 1b + LI64 r35, 0d + CP r36, r35 + 7: JAL r31, r0, :opaque + JLTU r36, r1, :0 + JMP :1 + 0: CP r37, r35 + 8: JAL r31, r0, :opaque + JLTU r37, r1, :2 + CP r38, r34 + JMP :3 + 2: JNE r37, r33, :4 + CP r38, r32 + 3: ANDI r39, r38, 255d + JNE r39, r35, :5 + JMP :6 + 5: ADDI64 r36, r36, 1d + 6: JMP :7 + 4: ADDI64 r37, r37, 1d + JMP :8 + 1: LD r31, r254, 0a, 72h + ADDI64 r254, r254, 72d + JALA r0, r31, 0a +opaque: + LI64 r1, 2147483648d + JALA r0, r31, 0a +timed out +code size: 218 +ret: 2147483648 +status: Ok(()) diff --git a/offense.hb b/offense.hb new file mode 100644 index 00000000..e69de29b