Rust · 3593 bytes Raw Blame History
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 program(name: &str) -> PathBuf {
8 let path = PathBuf::from("test_programs").join(name);
9 assert!(path.exists(), "missing program 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 #[test]
23 fn integer16_read_uses_wide_reader_in_ir_and_asm() {
24 let source = program("integer16_read.f90");
25
26 let opt_ir = capture_text(
27 CaptureRequest {
28 input: source.clone(),
29 requested: BTreeSet::from([Stage::OptIr]),
30 opt_level: OptLevel::O2,
31 },
32 Stage::OptIr,
33 );
34 assert!(
35 opt_ir.contains("call @afs_read_int128("),
36 "optimized IR should route integer(16) read through the wide runtime reader:\n{}",
37 opt_ir
38 );
39
40 let asm = capture_text(
41 CaptureRequest {
42 input: source,
43 requested: BTreeSet::from([Stage::Asm]),
44 opt_level: OptLevel::O2,
45 },
46 Stage::Asm,
47 );
48 assert!(
49 asm.contains("_afs_read_int128"),
50 "assembly should reference the wide runtime reader symbol:\n{}",
51 asm
52 );
53 }
54
55 #[test]
56 fn integer16_read_runs_across_all_opt_levels() {
57 for level in [
58 OptLevel::O0,
59 OptLevel::O1,
60 OptLevel::O2,
61 OptLevel::O3,
62 OptLevel::Os,
63 OptLevel::Ofast,
64 ] {
65 let result = capture_from_path(&CaptureRequest {
66 input: program("integer16_read.f90"),
67 requested: BTreeSet::from([Stage::Run]),
68 opt_level: level,
69 })
70 .unwrap_or_else(|e| panic!("integer(16) read should run at {:?}:\n{}", level, e));
71
72 let run = result
73 .get(Stage::Run)
74 .and_then(CapturedStage::as_run)
75 .expect("missing run capture");
76
77 assert_eq!(
78 run.exit_code, 0,
79 "expected successful integer(16) read run at {:?}:\n{:#?}",
80 level, run
81 );
82 assert!(
83 run.stdout
84 .contains("170141183460469231731687303715884105727"),
85 "wide positive integer(16) read should survive at {:?}:\n{}",
86 level,
87 run.stdout
88 );
89 assert!(
90 run.stdout
91 .contains("-170141183460469231731687303715884105727"),
92 "wide negative integer(16) read should survive at {:?}:\n{}",
93 level,
94 run.stdout
95 );
96 }
97 }
98
99 #[test]
100 fn integer16_read_object_snapshot_is_deterministic_at_o2() {
101 let source = program("integer16_read.f90");
102 let first = capture_text(
103 CaptureRequest {
104 input: source.clone(),
105 requested: BTreeSet::from([Stage::Obj]),
106 opt_level: OptLevel::O2,
107 },
108 Stage::Obj,
109 );
110 let second = capture_text(
111 CaptureRequest {
112 input: source,
113 requested: BTreeSet::from([Stage::Obj]),
114 opt_level: OptLevel::O2,
115 },
116 Stage::Obj,
117 );
118
119 assert_eq!(
120 first, second,
121 "integer(16) read object snapshots should be deterministic at O2"
122 );
123 }
124