Skip to content

Commit 4d97b28

Browse files
committed
Support revisions for codegen tests
`compile-flags: -Copt-level` will avoid adding -O. Similarly for -g and -Cdebuglevel.
1 parent dcf5482 commit 4d97b28

File tree

6 files changed

+115
-49
lines changed

6 files changed

+115
-49
lines changed

src/librustc_codegen_llvm/attributes.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -155,8 +155,6 @@ pub fn from_fn_attrs(
155155
let codegen_fn_attrs = id.map(|id| cx.tcx.codegen_fn_attrs(id))
156156
.unwrap_or_else(|| CodegenFnAttrs::new());
157157

158-
inline(cx, llfn, codegen_fn_attrs.inline);
159-
160158
match codegen_fn_attrs.optimize {
161159
OptimizeAttr::None => {
162160
match cx.tcx.sess.opts.optimize {
@@ -173,7 +171,7 @@ pub fn from_fn_attrs(
173171
OptLevel::No => {
174172
llvm::Attribute::MinSize.unapply_llfn(Function, llfn);
175173
llvm::Attribute::OptimizeForSize.unapply_llfn(Function, llfn);
176-
llvm::Attribute::OptimizeNone.apply_llfn(Function, llfn);
174+
llvm::Attribute::OptimizeNone.unapply_llfn(Function, llfn);
177175
}
178176
_ => {}
179177
}
@@ -190,6 +188,8 @@ pub fn from_fn_attrs(
190188
}
191189
}
192190

191+
inline(cx, llfn, codegen_fn_attrs.inline);
192+
193193
// The `uwtable` attribute according to LLVM is:
194194
//
195195
// This attribute indicates that the ABI being targeted requires that an

src/librustc_codegen_llvm/declare.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ fn declare_raw_fn(
6565
}
6666
}
6767

68-
// FIXME(opt): this is kinda duplicated with similar code in attributes::from_fm_attrs
68+
// FIXME(opt): this is kinda duplicated with similar code in attributes::from_fn_attrs
6969
match cx.tcx.sess.opts.optimize {
7070
OptLevel::Size => {
7171
llvm::Attribute::MinSize.unapply_llfn(Function, llfn);
@@ -80,7 +80,7 @@ fn declare_raw_fn(
8080
OptLevel::No => {
8181
llvm::Attribute::MinSize.unapply_llfn(Function, llfn);
8282
llvm::Attribute::OptimizeForSize.unapply_llfn(Function, llfn);
83-
llvm::Attribute::OptimizeNone.apply_llfn(Function, llfn);
83+
llvm::Attribute::OptimizeNone.unapply_llfn(Function, llfn);
8484
}
8585
_ => {}
8686
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
// revisions: NO-OPT SIZE-OPT SPEED-OPT
2+
//[NO-OPT] compile-flags: -Copt-level=0
3+
//[SIZE-OPT] compile-flags: -Copt-level=s
4+
//[SPEED-OPT] compile-flags: -Copt-level=3
5+
6+
#![crate_type="rlib"]
7+
8+
#[no_mangle]
9+
#[inline(always)]
10+
pub extern "C" fn callee() -> u32 {
11+
4 + 4
12+
}
13+
14+
// CHECK-LABEL: caller
15+
// SIZE-OPT: ret i32 8
16+
// SPEED-OPT: ret i32 8
17+
// NO-OPT: ret i32 8
18+
#[no_mangle]
19+
pub extern "C" fn caller() -> u32 {
20+
callee()
21+
}

src/test/codegen/optimize-attr-1.rs

+30-29
Original file line numberDiff line numberDiff line change
@@ -1,49 +1,50 @@
11
// revisions: NO-OPT SIZE-OPT SPEED-OPT
2-
// [NO-OPT]compile-flags: -Copt-level=0
3-
// [SIZE-OPT]compile-flags: -Copt-level=s
4-
// [SPEED-OPT]compile-flags: -Copt-level=3
2+
//[NO-OPT] compile-flags: -Copt-level=0 -Ccodegen-units=1
3+
//[SIZE-OPT] compile-flags: -Copt-level=s -Ccodegen-units=1
4+
//[SPEED-OPT] compile-flags: -Copt-level=3 -Ccodegen-units=1
55

66
#![feature(optimize_attribute)]
77
#![crate_type="rlib"]
88

9-
// NO-OPT: Function Attrs:{{.*}}optnone
10-
// NO-OPT-NOT: {{optsize|minsize}}
11-
// NO-OPT-NEXT: @nothing
9+
// CHECK-LABEL: define i32 @nothing
10+
// CHECK-SAME: [[NOTHING_ATTRS:#[0-9]+]]
1211
// NO-OPT: ret i32 %1
13-
//
14-
// SIZE-OPT: Function Attrs:{{.*}}optsize
15-
// SIZE-OPT-NOT: {{minsize|optnone}}
16-
// SIZE-OPT-NEXT: @nothing
17-
// SIZE-OPT-NEXT: start
18-
// SIZE-OPT-NEXT: ret i32 4
19-
//
20-
// SPEED-OPT: Function Attrs:
21-
// SPEED-OPT-NOT: {{minsize|optnone|optsize}}
22-
// SPEED-OPT-NEXT: @nothing
23-
// SPEED-OPT-NEXT: start
24-
// SPEED-OPT-NEXT: ret i32 4
12+
// SIZE-OPT: ret i32 4
13+
// SPEEC-OPT: ret i32 4
2514
#[no_mangle]
2615
pub fn nothing() -> i32 {
2716
2 + 2
2817
}
2918

30-
// CHECK: Function Attrs:{{.*}} minsize{{.*}}optsize
31-
// CHECK-NEXT: @size
32-
// CHECK-NEXT: start
33-
// CHECK-NEXT: ret i32 4
19+
// CHECK-LABEL: define i32 @size
20+
// CHECK-SAME: [[SIZE_ATTRS:#[0-9]+]]
21+
// NO-OPT: ret i32 %1
22+
// SIZE-OPT: ret i32 6
23+
// SPEED-OPT: ret i32 6
3424
#[optimize(size)]
3525
#[no_mangle]
3626
pub fn size() -> i32 {
37-
2 + 2
27+
3 + 3
3828
}
3929

40-
// CHECK: Function Attrs:
41-
// CHECK-NOT: {{minsize|optsize|optnone}}
42-
// CHECK-NEXT: @speed
43-
// CHECK-NEXT: start
44-
// CHECK-NEXT: ret i32 4
30+
// CHECK-LABEL: define i32 @speed
31+
// NO-OPT-SAME: [[NOTHING_ATTRS]]
32+
// SPEED-OPT-SAME: [[NOTHING_ATTRS]]
33+
// SIZE-OPT-SAME: [[SPEED_ATTRS:#[0-9]+]]
34+
// NO-OPT: ret i32 %1
35+
// SIZE-OPT: ret i32 8
36+
// SPEED-OPT: ret i32 8
4537
#[optimize(speed)]
4638
#[no_mangle]
4739
pub fn speed() -> i32 {
48-
2 + 2
40+
4 + 4
4941
}
42+
43+
// NO-OPT-DAG: attributes [[SIZE_ATTRS]] = {{.*}}minsize{{.*}}optsize{{.*}}
44+
// SPEED-OPT-DAG: attributes [[SIZE_ATTRS]] = {{.*}}minsize{{.*}}optsize{{.*}}
45+
// SIZE-OPT-DAG: attributes [[NOTHING_ATTRS]] = {{.*}}optsize{{.*}}
46+
// SIZE-OPT-DAG: attributes [[SIZE_ATTRS]] = {{.*}}minsize{{.*}}optsize{{.*}}
47+
48+
// SIZE-OPT: attributes [[SPEED_ATTRS]]
49+
// SIZE-OPT-NOT: minsize
50+
// SIZE-OPT-NOT: optsize

src/tools/compiletest/src/header.rs

+2
Original file line numberDiff line numberDiff line change
@@ -542,6 +542,8 @@ fn iter_header(testfile: &Path, cfg: Option<&str>, it: &mut dyn FnMut(&str)) {
542542
"#"
543543
};
544544

545+
// FIXME: would be nice to allow some whitespace between comment and brace :)
546+
// It took me like 2 days to debug why compile-flags weren’t taken into account for my test :)
545547
let comment_with_brace = comment.to_string() + "[";
546548

547549
let rdr = BufReader::new(File::open(testfile).unwrap());

src/tools/compiletest/src/runtest.rs

+57-15
Original file line numberDiff line numberDiff line change
@@ -552,9 +552,10 @@ impl<'test> TestCx<'test> {
552552
.args(&["--target", &self.config.target])
553553
.arg("-L")
554554
.arg(&aux_dir)
555-
.args(self.split_maybe_args(&self.config.target_rustcflags))
556555
.args(&self.props.compile_flags)
557556
.envs(self.props.exec_env.clone());
557+
self.maybe_add_external_args(&mut rustc,
558+
self.split_maybe_args(&self.config.target_rustcflags));
558559

559560
let src = match read_from {
560561
ReadFrom::Stdin(src) => Some(src),
@@ -587,6 +588,15 @@ impl<'test> TestCx<'test> {
587588
}
588589
}
589590

591+
fn set_revision_flags(&self, cmd: &mut Command) {
592+
if let Some(revision) = self.revision {
593+
// Normalize revisions to be lowercase and replace `-`s with `_`s.
594+
// Otherwise the `--cfg` flag is not valid.
595+
let normalized_revision = revision.to_lowercase().replace("-", "_");
596+
cmd.args(&["--cfg", &normalized_revision]);
597+
}
598+
}
599+
590600
fn typecheck_source(&self, src: String) -> ProcRes {
591601
let mut rustc = Command::new(&self.config.rustc_path);
592602

@@ -612,12 +622,9 @@ impl<'test> TestCx<'test> {
612622
.arg(&self.config.build_base)
613623
.arg("-L")
614624
.arg(aux_dir);
615-
616-
if let Some(revision) = self.revision {
617-
rustc.args(&["--cfg", revision]);
618-
}
619-
620-
rustc.args(self.split_maybe_args(&self.config.target_rustcflags));
625+
self.set_revision_flags(&mut rustc);
626+
self.maybe_add_external_args(&mut rustc,
627+
self.split_maybe_args(&self.config.target_rustcflags));
621628
rustc.args(&self.props.compile_flags);
622629

623630
self.compose_and_run_compiler(rustc, Some(src))
@@ -1119,6 +1126,35 @@ impl<'test> TestCx<'test> {
11191126
Some(new_options.join(" "))
11201127
}
11211128

1129+
fn maybe_add_external_args(&self, cmd: &mut Command, args: Vec<String>) {
1130+
// Filter out the arguments that should not be added by runtest here.
1131+
//
1132+
// Notable use-cases are: do not add our optimisation flag if
1133+
// `compile-flags: -Copt-level=x` and similar for debug-info level as well.
1134+
const OPT_FLAGS: &[&str] = &["-O", "-Copt-level=", /*-C<space>*/"opt-level="];
1135+
const DEBUG_FLAGS: &[&str] = &["-g", "-Cdebuginfo=", /*-C<space>*/"debuginfo="];
1136+
1137+
// FIXME: ideally we would "just" check the `cmd` itself, but it does not allow inspecting
1138+
// its arguments. They need to be collected separately. For now I cannot be bothered to
1139+
// implement this the "right" way.
1140+
let have_opt_flag = self.props.compile_flags.iter().any(|arg| {
1141+
OPT_FLAGS.iter().any(|f| arg.starts_with(f))
1142+
});
1143+
let have_debug_flag = self.props.compile_flags.iter().any(|arg| {
1144+
DEBUG_FLAGS.iter().any(|f| arg.starts_with(f))
1145+
});
1146+
1147+
for arg in args {
1148+
if OPT_FLAGS.iter().any(|f| arg.starts_with(f)) && have_opt_flag {
1149+
continue;
1150+
}
1151+
if DEBUG_FLAGS.iter().any(|f| arg.starts_with(f)) && have_debug_flag {
1152+
continue;
1153+
}
1154+
cmd.arg(arg);
1155+
}
1156+
}
1157+
11221158
fn check_debugger_output(&self, debugger_run_result: &ProcRes, check_lines: &[String]) {
11231159
let num_check_lines = check_lines.len();
11241160

@@ -1707,10 +1743,7 @@ impl<'test> TestCx<'test> {
17071743

17081744
rustc.arg(&format!("--target={}", target));
17091745
}
1710-
1711-
if let Some(revision) = self.revision {
1712-
rustc.args(&["--cfg", revision]);
1713-
}
1746+
self.set_revision_flags(&mut rustc);
17141747

17151748
if !is_rustdoc {
17161749
if let Some(ref incremental_dir) = self.props.incremental_dir {
@@ -1810,9 +1843,11 @@ impl<'test> TestCx<'test> {
18101843
}
18111844

18121845
if self.props.force_host {
1813-
rustc.args(self.split_maybe_args(&self.config.host_rustcflags));
1846+
self.maybe_add_external_args(&mut rustc,
1847+
self.split_maybe_args(&self.config.host_rustcflags));
18141848
} else {
1815-
rustc.args(self.split_maybe_args(&self.config.target_rustcflags));
1849+
self.maybe_add_external_args(&mut rustc,
1850+
self.split_maybe_args(&self.config.target_rustcflags));
18161851
if !is_rustdoc {
18171852
if let Some(ref linker) = self.config.linker {
18181853
rustc.arg(format!("-Clinker={}", linker));
@@ -2065,12 +2100,19 @@ impl<'test> TestCx<'test> {
20652100
.arg("--input-file")
20662101
.arg(irfile)
20672102
.arg(&self.testpaths.file);
2103+
// It would be more appropriate to make most of the arguments configurable through
2104+
// a comment-attribute similar to `compile-flags`. For example, --check-prefixes is a very
2105+
// useful flag.
2106+
//
2107+
// For now, though…
2108+
if let Some(rev) = self.revision {
2109+
let prefixes = format!("CHECK,{}", rev);
2110+
filecheck.args(&["--check-prefixes", &prefixes]);
2111+
}
20682112
self.compose_and_run(filecheck, "", None, None)
20692113
}
20702114

20712115
fn run_codegen_test(&self) {
2072-
assert!(self.revision.is_none(), "revisions not relevant here");
2073-
20742116
if self.config.llvm_filecheck.is_none() {
20752117
self.fatal("missing --llvm-filecheck");
20762118
}

0 commit comments

Comments
 (0)