fortrangoingonforty/armfortas / 3e044f2

Browse files

Test scalar-tail peeling produces correct boundary values at c(28)/c(29)/c(31)

Authored by mfwolffe <wolffemf@dukes.jmu.edu>
SHA
3e044f240b6c64419c0690071ab4e0ce6c873b0a
Parents
329f3d3
Tree
6df6722

1 changed file

StatusFile+-
A tests/vectorize_scalar_tail.rs 76 0
tests/vectorize_scalar_tail.rsadded
@@ -0,0 +1,76 @@
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(name: &str) -> PathBuf {
8
+    let path = PathBuf::from("test_programs").join(name);
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 capture_run_stdout(request: CaptureRequest) -> String {
23
+    let result = capture_from_path(&request).expect("capture should succeed");
24
+    match result.get(Stage::Run) {
25
+        Some(CapturedStage::Run(run)) => run.stdout.clone(),
26
+        _ => panic!("missing run stage"),
27
+    }
28
+}
29
+
30
+#[test]
31
+fn o3_vectorizes_head_and_peels_scalar_tail() {
32
+    let source = fixture("do_loop_vectorize_scalar_tail.f90");
33
+
34
+    let o3_ir = capture_text(
35
+        CaptureRequest {
36
+            input: source.clone(),
37
+            requested: BTreeSet::from([Stage::OptIr]),
38
+            opt_level: OptLevel::O3,
39
+        },
40
+        Stage::OptIr,
41
+    );
42
+    // Vector head fired (vload / vstore present).
43
+    assert!(
44
+        o3_ir.contains("vload") && o3_ir.contains("vstore"),
45
+        "expected vector head with vload/vstore in IR:\n{}",
46
+        o3_ir
47
+    );
48
+    assert!(
49
+        o3_ir.contains("<4 x i32>"),
50
+        "expected i32 vector accumulator in IR:\n{}",
51
+        o3_ir
52
+    );
53
+
54
+    let stdout = capture_run_stdout(CaptureRequest {
55
+        input: source,
56
+        requested: BTreeSet::from([Stage::Run]),
57
+        opt_level: OptLevel::O3,
58
+    });
59
+    let trimmed: Vec<&str> = stdout
60
+        .lines()
61
+        .map(|l| l.trim())
62
+        .filter(|l| !l.is_empty())
63
+        .collect();
64
+    assert_eq!(trimmed.len(), 5, "expected five output lines:\n{}", stdout);
65
+
66
+    // total = sum(3*i for i=1..31) = 1488
67
+    assert_eq!(trimmed[0], "1488", "wrong total, got {:?}", trimmed[0]);
68
+    // c(1) = 1 + 2 = 3
69
+    assert_eq!(trimmed[1], "3", "c(1) wrong, got {:?}", trimmed[1]);
70
+    // c(28) = 28 + 56 = 84  (last lane of last vector iter)
71
+    assert_eq!(trimmed[2], "84", "c(28) wrong, got {:?}", trimmed[2]);
72
+    // c(29) = 29 + 58 = 87  (first scalar tail iteration)
73
+    assert_eq!(trimmed[3], "87", "c(29) wrong, got {:?}", trimmed[3]);
74
+    // c(31) = 31 + 62 = 93  (last scalar tail iteration)
75
+    assert_eq!(trimmed[4], "93", "c(31) wrong, got {:?}", trimmed[4]);
76
+}