fortrangoingonforty/armfortas / 71d2ac0

Browse files

Add GVN audit regression

Authored by mfwolffe <wolffemf@dukes.jmu.edu>
SHA
71d2ac0aec5612bbc0fb6d4d260d59a13f515013
Parents
89b9a8f
Tree
cb19e49

3 changed files

StatusFile+-
A test_programs/gvn_cross_block.f90 28 0
A tests/fixtures/gvn_cross_block.f90 12 0
A tests/opt_audit_29_8.rs 65 0
test_programs/gvn_cross_block.f90added
@@ -0,0 +1,28 @@
1
+program gvn_cross_block
2
+  implicit none
3
+  integer :: left, right
4
+
5
+  left = 10
6
+  right = 4
7
+
8
+  print *, eval_branch(left, right, 1)
9
+  print *, eval_branch(left, right, -1)
10
+
11
+contains
12
+
13
+  integer function eval_branch(a, b, flag)
14
+    implicit none
15
+    integer, value :: a, b, flag
16
+    integer :: tmp
17
+
18
+    tmp = a + b
19
+    if (flag > 0) then
20
+      eval_branch = tmp + (a + b)
21
+    else
22
+      eval_branch = tmp - (a + b)
23
+    end if
24
+  end function eval_branch
25
+end program gvn_cross_block
26
+
27
+! CHECK: 28
28
+! CHECK: 0
tests/fixtures/gvn_cross_block.f90added
@@ -0,0 +1,12 @@
1
+integer function gvn_cross_block(a, b, flag)
2
+  implicit none
3
+  integer, value :: a, b, flag
4
+  integer :: tmp
5
+
6
+  tmp = a + b
7
+  if (flag > 0) then
8
+    gvn_cross_block = tmp + (a + b)
9
+  else
10
+    gvn_cross_block = tmp - (a + b)
11
+  end if
12
+end function gvn_cross_block
tests/opt_audit_29_8.rsadded
@@ -0,0 +1,65 @@
1
+use std::collections::BTreeSet;
2
+use std::path::PathBuf;
3
+
4
+use armfortas::driver::OptLevel;
5
+use armfortas::testing::{capture_from_path, CaptureRequest, CapturedStage, Stage};
6
+
7
+fn fixture(path: &str) -> PathBuf {
8
+    let path = PathBuf::from(path);
9
+    assert!(path.exists(), "missing test fixture {}", path.display());
10
+    path
11
+}
12
+
13
+fn capture_text(request: CaptureRequest, stage: Stage) -> String {
14
+    let result = capture_from_path(&request).expect("capture should succeed");
15
+    match result.get(stage) {
16
+        Some(CapturedStage::Text(text)) => text.clone(),
17
+        Some(CapturedStage::Run(_)) => panic!("expected text stage for {}", stage.as_str()),
18
+        None => panic!("missing requested stage {}", stage.as_str()),
19
+    }
20
+}
21
+
22
+fn count(haystack: &str, needle: &str) -> usize {
23
+    haystack.matches(needle).count()
24
+}
25
+
26
+#[test]
27
+fn gvn_reduces_cross_block_recomputation_for_value_args() {
28
+    let source = fixture("tests/fixtures/gvn_cross_block.f90");
29
+
30
+    let ir_o0 = capture_text(
31
+        CaptureRequest {
32
+            input: source.clone(),
33
+            requested: BTreeSet::from([Stage::Ir]),
34
+            opt_level: OptLevel::O0,
35
+        },
36
+        Stage::Ir,
37
+    );
38
+    let opt_ir_o2 = capture_text(
39
+        CaptureRequest {
40
+            input: source,
41
+            requested: BTreeSet::from([Stage::OptIr]),
42
+            opt_level: OptLevel::O2,
43
+        },
44
+        Stage::OptIr,
45
+    );
46
+
47
+    assert_eq!(
48
+        count(&ir_o0, " = iadd "),
49
+        4,
50
+        "lowered IR should contain four adds before optimization rewrites:\n{}",
51
+        ir_o0
52
+    );
53
+    assert_eq!(
54
+        count(&opt_ir_o2, " = iadd "),
55
+        2,
56
+        "O2 optimized IR should reuse the dominating a+b value across blocks:\n{}",
57
+        opt_ir_o2
58
+    );
59
+    assert_eq!(
60
+        count(&opt_ir_o2, "iadd %0, %1"),
61
+        1,
62
+        "optimized IR should materialize the source add only once:\n{}",
63
+        opt_ir_o2
64
+    );
65
+}