From 10c668190cb419b539a36214237382c6689f7daf Mon Sep 17 00:00:00 2001 From: Xiang Fan Date: Sat, 28 Sep 2019 07:13:53 +0800 Subject: [PATCH] Gate llvm.sideeffect under -Z insert-sideeffect --- src/librustc/session/config.rs | 3 +++ src/librustc_codegen_llvm/intrinsic.rs | 6 ++++-- src/librustc_codegen_ssa/mir/block.rs | 16 +++++++++------- src/test/codegen/alloc-optimisation.rs | 3 +-- src/test/codegen/dealloc-no-unwind.rs | 2 +- src/test/codegen/issue-34947-pow-i32.rs | 9 +++------ src/test/codegen/issue-45222.rs | 6 ------ src/test/codegen/naked-functions.rs | 10 ++++++---- .../codegen/non-terminate/infinite-loop-1.rs | 2 +- .../codegen/non-terminate/infinite-loop-2.rs | 2 +- .../codegen/non-terminate/infinite-recursion.rs | 2 +- src/test/codegen/repeat-trusted-len.rs | 6 +----- src/test/codegen/vec-clear.rs | 6 ------ src/test/codegen/vec-iter-collect-len.rs | 4 +++- src/test/codegen/vec-optimizes-away.rs | 2 +- .../inline-always-many-cgu/Makefile | 2 +- 16 files changed, 36 insertions(+), 45 deletions(-) diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs index 73b731b07619d..abfbba53b5936 100644 --- a/src/librustc/session/config.rs +++ b/src/librustc/session/config.rs @@ -1472,6 +1472,9 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options, "which mangling version to use for symbol names"), binary_dep_depinfo: bool = (false, parse_bool, [TRACKED], "include artifacts (sysroot, crate dependencies) used during compilation in dep-info"), + insert_sideeffect: bool = (false, parse_bool, [TRACKED], + "fix undefined behavior when a thread doesn't eventually make progress \ + (such as entering an empty infinite loop) by inserting llvm.sideeffect"), } pub fn default_lib_output() -> CrateType { diff --git a/src/librustc_codegen_llvm/intrinsic.rs b/src/librustc_codegen_llvm/intrinsic.rs index a8734d338df17..e4ac176576053 100644 --- a/src/librustc_codegen_llvm/intrinsic.rs +++ b/src/librustc_codegen_llvm/intrinsic.rs @@ -726,8 +726,10 @@ impl IntrinsicCallMethods<'tcx> for Builder<'a, 'll, 'tcx> { } fn sideeffect(&mut self) { - let fnname = self.get_intrinsic(&("llvm.sideeffect")); - self.call(fnname, &[], None); + if self.tcx.sess.opts.debugging_opts.insert_sideeffect { + let fnname = self.get_intrinsic(&("llvm.sideeffect")); + self.call(fnname, &[], None); + } } fn va_start(&mut self, va_list: &'ll Value) -> &'ll Value { diff --git a/src/librustc_codegen_ssa/mir/block.rs b/src/librustc_codegen_ssa/mir/block.rs index 99d70e6bb8253..8e3243f5e7bd0 100644 --- a/src/librustc_codegen_ssa/mir/block.rs +++ b/src/librustc_codegen_ssa/mir/block.rs @@ -157,13 +157,15 @@ impl<'a, 'tcx> TerminatorCodegenHelper<'a, 'tcx> { bx: &mut Bx, targets: &[mir::BasicBlock], ) { - if targets.iter().any(|target| { - *target <= *self.bb - && target - .start_location() - .is_predecessor_of(self.bb.start_location(), mir) - }) { - bx.sideeffect(); + if bx.tcx().sess.opts.debugging_opts.insert_sideeffect { + if targets.iter().any(|target| { + *target <= *self.bb + && target + .start_location() + .is_predecessor_of(self.bb.start_location(), mir) + }) { + bx.sideeffect(); + } } } } diff --git a/src/test/codegen/alloc-optimisation.rs b/src/test/codegen/alloc-optimisation.rs index c1e36a17ec291..c3ffaeb9547b3 100644 --- a/src/test/codegen/alloc-optimisation.rs +++ b/src/test/codegen/alloc-optimisation.rs @@ -7,8 +7,7 @@ pub fn alloc_test(data: u32) { // CHECK-LABEL: @alloc_test // CHECK-NEXT: start: - // CHECK-NOT: alloc - // CHECK: ret void + // CHECK-NEXT: ret void let x = Box::new(data); drop(x); } diff --git a/src/test/codegen/dealloc-no-unwind.rs b/src/test/codegen/dealloc-no-unwind.rs index f8fc663169d9b..ff21b4caa83c3 100644 --- a/src/test/codegen/dealloc-no-unwind.rs +++ b/src/test/codegen/dealloc-no-unwind.rs @@ -17,7 +17,7 @@ impl Drop for A { pub fn a(a: Box) { // CHECK-LABEL: define void @a // CHECK: call void @__rust_dealloc - // CHECK: call void @foo + // CHECK-NEXT: call void @foo let _a = A; drop(a); } diff --git a/src/test/codegen/issue-34947-pow-i32.rs b/src/test/codegen/issue-34947-pow-i32.rs index bd8b79adf43b6..653da8e8b5f7b 100644 --- a/src/test/codegen/issue-34947-pow-i32.rs +++ b/src/test/codegen/issue-34947-pow-i32.rs @@ -6,11 +6,8 @@ #[no_mangle] pub fn issue_34947(x: i32) -> i32 { // CHECK: mul - // CHECK-NOT: br label - // CHECK: mul - // CHECK-NOT: br label - // CHECK: mul - // CHECK-NOT: br label - // CHECK: ret + // CHECK-NEXT: mul + // CHECK-NEXT: mul + // CHECK-NEXT: ret x.pow(5) } diff --git a/src/test/codegen/issue-45222.rs b/src/test/codegen/issue-45222.rs index 894927c5c3351..7aadc8a095498 100644 --- a/src/test/codegen/issue-45222.rs +++ b/src/test/codegen/issue-45222.rs @@ -1,9 +1,3 @@ -// ignore-test - -// FIXME: -// LLVM can't optimize some loops with a large number of iterations because of -// @llvm.sideeffect() (see also #59546) - // compile-flags: -O // ignore-debug: the debug assertions get in the way diff --git a/src/test/codegen/naked-functions.rs b/src/test/codegen/naked-functions.rs index fb683a49a8a80..2050193b61b54 100644 --- a/src/test/codegen/naked-functions.rs +++ b/src/test/codegen/naked-functions.rs @@ -1,3 +1,5 @@ +// ignore-tidy-linelength + // compile-flags: -C no-prepopulate-passes #![crate_type = "lib"] @@ -51,7 +53,7 @@ pub fn naked_with_args_and_return(a: isize) -> isize { #[naked] pub fn naked_recursive() { // CHECK-NEXT: {{.+}}: - // CHECK: call void @naked_empty() + // CHECK-NEXT: call void @naked_empty() // FIXME(#39685) Avoid one block per call. // CHECK-NEXT: br label %bb1 @@ -59,19 +61,19 @@ pub fn naked_recursive() { naked_empty(); - // CHECK: %{{[0-9]+}} = call i{{[0-9]+}} @naked_with_return() + // CHECK-NEXT: %{{[0-9]+}} = call i{{[0-9]+}} @naked_with_return() // FIXME(#39685) Avoid one block per call. // CHECK-NEXT: br label %bb2 // CHECK: bb2: - // CHECK: %{{[0-9]+}} = call i{{[0-9]+}} @naked_with_args_and_return(i{{[0-9]+}} %{{[0-9]+}}) + // CHECK-NEXT: %{{[0-9]+}} = call i{{[0-9]+}} @naked_with_args_and_return(i{{[0-9]+}} %{{[0-9]+}}) // FIXME(#39685) Avoid one block per call. // CHECK-NEXT: br label %bb3 // CHECK: bb3: - // CHECK: call void @naked_with_args(i{{[0-9]+}} %{{[0-9]+}}) + // CHECK-NEXT: call void @naked_with_args(i{{[0-9]+}} %{{[0-9]+}}) // FIXME(#39685) Avoid one block per call. // CHECK-NEXT: br label %bb4 diff --git a/src/test/codegen/non-terminate/infinite-loop-1.rs b/src/test/codegen/non-terminate/infinite-loop-1.rs index fa9c66b47c0a4..56b360e0a7f48 100644 --- a/src/test/codegen/non-terminate/infinite-loop-1.rs +++ b/src/test/codegen/non-terminate/infinite-loop-1.rs @@ -1,4 +1,4 @@ -// compile-flags: -C opt-level=3 +// compile-flags: -C opt-level=3 -Z insert-sideeffect #![crate_type = "lib"] diff --git a/src/test/codegen/non-terminate/infinite-loop-2.rs b/src/test/codegen/non-terminate/infinite-loop-2.rs index 81d62ab33d778..2921ab6dc04af 100644 --- a/src/test/codegen/non-terminate/infinite-loop-2.rs +++ b/src/test/codegen/non-terminate/infinite-loop-2.rs @@ -1,4 +1,4 @@ -// compile-flags: -C opt-level=3 +// compile-flags: -C opt-level=3 -Z insert-sideeffect #![crate_type = "lib"] diff --git a/src/test/codegen/non-terminate/infinite-recursion.rs b/src/test/codegen/non-terminate/infinite-recursion.rs index 6d1f2d4bf8f4a..1f292ce379fc0 100644 --- a/src/test/codegen/non-terminate/infinite-recursion.rs +++ b/src/test/codegen/non-terminate/infinite-recursion.rs @@ -1,4 +1,4 @@ -// compile-flags: -C opt-level=3 +// compile-flags: -C opt-level=3 -Z insert-sideeffect #![crate_type = "lib"] diff --git a/src/test/codegen/repeat-trusted-len.rs b/src/test/codegen/repeat-trusted-len.rs index 40399e8f76f01..87f29f6047c6a 100644 --- a/src/test/codegen/repeat-trusted-len.rs +++ b/src/test/codegen/repeat-trusted-len.rs @@ -14,10 +14,6 @@ pub fn helper(_: usize) { // CHECK-LABEL: @repeat_take_collect #[no_mangle] pub fn repeat_take_collect() -> Vec { -// FIXME: At the time of writing LLVM transforms this loop into a single -// `store` and then a `memset` with size = 99999. The correct check should be: -// call void @llvm.memset.p0i8.[[USIZE]](i8* {{(nonnull )?}}align 1 %{{[a-z0-9.]+}}, i8 42, [[USIZE]] 100000, i1 false) - -// CHECK: call void @llvm.memset.p0i8.[[USIZE]](i8* {{(nonnull )?}}align 1 %{{[a-z0-9.]+}}, i8 42, [[USIZE]] 99999, i1 false) +// CHECK: call void @llvm.memset.p0i8.[[USIZE]](i8* {{(nonnull )?}}align 1 %{{[0-9]+}}, i8 42, [[USIZE]] 100000, i1 false) iter::repeat(42).take(100000).collect() } diff --git a/src/test/codegen/vec-clear.rs b/src/test/codegen/vec-clear.rs index 22e1248907a76..b9ffce8b0cb3d 100644 --- a/src/test/codegen/vec-clear.rs +++ b/src/test/codegen/vec-clear.rs @@ -1,9 +1,3 @@ -// ignore-test - -// FIXME: -// LLVM can't optimize some loops with unknown number of iterations because of -// @llvm.sideeffect() (see also #59546) - // ignore-debug: the debug assertions get in the way // compile-flags: -O diff --git a/src/test/codegen/vec-iter-collect-len.rs b/src/test/codegen/vec-iter-collect-len.rs index 893d1b50a4a97..73348ddd063dc 100644 --- a/src/test/codegen/vec-iter-collect-len.rs +++ b/src/test/codegen/vec-iter-collect-len.rs @@ -5,6 +5,8 @@ #[no_mangle] pub fn get_len() -> usize { - // CHECK-COUNT-1: {{^define}} + // CHECK-LABEL: @get_len + // CHECK-NOT: call + // CHECK-NOT: invoke [1, 2, 3].iter().collect::>().len() } diff --git a/src/test/codegen/vec-optimizes-away.rs b/src/test/codegen/vec-optimizes-away.rs index 08d0332651cb7..ebede0908c6c4 100644 --- a/src/test/codegen/vec-optimizes-away.rs +++ b/src/test/codegen/vec-optimizes-away.rs @@ -8,6 +8,6 @@ pub fn sum_me() -> i32 { // CHECK-LABEL: @sum_me // CHECK-NEXT: {{^.*:$}} - // CHECK: ret i32 6 + // CHECK-NEXT: ret i32 6 vec![1, 2, 3].iter().sum::() } diff --git a/src/test/run-make-fulldeps/inline-always-many-cgu/Makefile b/src/test/run-make-fulldeps/inline-always-many-cgu/Makefile index fd09df78ffa8d..0cab955f6442b 100644 --- a/src/test/run-make-fulldeps/inline-always-many-cgu/Makefile +++ b/src/test/run-make-fulldeps/inline-always-many-cgu/Makefile @@ -2,7 +2,7 @@ all: $(RUSTC) foo.rs --emit llvm-ir -C codegen-units=2 - if cat $(TMPDIR)/*.ll | grep -v 'call void @llvm.sideeffect()' | $(CGREP) -e '\bcall\b'; then \ + if cat $(TMPDIR)/*.ll | $(CGREP) -e '\bcall\b'; then \ echo "found call instruction when one wasn't expected"; \ exit 1; \ fi