Repository navigation
Wrong optimization #98568
Description
Activity
Simplified the function a bit:
pub fn buggy(arr: Vec<i32>) -> i32 { let mut prev = 0; let mut cnt = 0; // The entire loop is optimized away in release: https://godbolt.org/z/j538GxzT1 for d in arr { if d > 0 { if prev < 0 { cnt += 1; } else { cnt = 1; } } else { if prev > 0 { cnt += 1; } else { cnt = 1; } } prev = d; } cnt } fn main() { let v = vec![-1,1]; let ans = buggy(v); // The right answer is 2. But when build with release, the output is 1 println!("{}", ans); }
It seems that something assumes that d = prev in the loop. However doing it explicitely by changing the condition to if d == prev doesn't trigger the bug.
- addedA-codegenArea: Code generationArea: Code generationI-unsoundIssue: A soundness hole (worst kind of bug), see: https://en.wikipedia.org/wiki/SoundnessIssue: A soundness hole (worst kind of bug), see: https://en.wikipedia.org/wiki/Soundnessregression-from-stable-to-stablePerformance or correctness regression from one stable version to another.Performance or correctness regression from one stable version to another.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.Relevant to the compiler team, which will review and decide on the PR/issue.I-prioritizeIssue needs a team member to assess the impact. Will be replaced by P-{low,medium,high,critical}Issue needs a team member to assess the impact. Will be replaced by P-{low,medium,high,critical}
on Jun 27, 2022 - addedA-LLVMArea: Code generation parts specific to LLVM. Both correctness bugs and optimization-related issues.Area: Code generation parts specific to LLVM. Both correctness bugs and optimization-related issues.
on Jun 27, 2022 Works with
-C no-prepopulate-passes, so presumably an LLVM miscompile. Assigning to me for investigation.Reacted by bestgopher, gembright stone hung, lotus.trait and Js2xxxThis C version has the same issue: https://godbolt.org/z/E86n349nr, so likely a LLVM bug.
@rustbot label: +A-LLVM
Miscompile still present on current main, and appears to be introduced during this
-indvarstransform: https://alive2.llvm.org/ce/z/I-4JjZUpstream issue: llvm/llvm-project#56242
WG-prioritization assigning priority (Zulip discussion).
@rustbot label -I-prioritize +P-critical
- addedP-criticalCritical priorityCritical priorityand removedI-prioritizeIssue needs a team member to assess the impact. Will be replaced by P-{low,medium,high,critical}Issue needs a team member to assess the impact. Will be replaced by P-{low,medium,high,critical}
on Jun 27, 2022 LLVM miscompile. The optimiser mistakenly analyses the loop as invariant.
Upstream fix: llvm/llvm-project@e4d1d0c
Reacted by bestgopher, llnut, gembright stone hung, wu aoxiang and Js2xxxReacted by Jubilee and Js2xxx
I tried this code:
I expected to see this happen: 5 is printed.
Instead, this happened: when build with release, the output is 2.
Meta
rustc --version --verbose:I also test all the following rust version at playground, and got wrong answer when build with release.
stable: 1.61.0
beta: 1.62.0-beta.6
nightly: 1.64.0-nightly (2022-06-25 20a6f3a)