Repository navigation
Open
Labels
A-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.C-bugCategory: This is a bug.Category: This is a bug.P-mediumMedium priorityMedium priorityS-has-bisectionStatus: A bisection has been found for this issueStatus: A bisection has been found for this issueT-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.regression-from-stable-to-stablePerformance or correctness regression from one stable version to another.Performance or correctness regression from one stable version to another.regression-untriagedUntriaged performance or correctness regression.Untriaged performance or correctness regression.
Milestone
Description
Not sure if it is related with LLVM.
https://godbolt.org/z/vhKoWYxM5
#[inline(never)]
pub fn f_index(data: &mut [u32]) {
for i in 0..data.len() {
data[i] += 1;
}
}Regression part in LBB0_4:
stable:
mov rax, rsi
and rax, -8
xor ecx, ecx
pcmpeqd xmm0, xmm0nightly:
movabs rax, 2305843009213693944
and rax, rsi
lea rcx, [4*rsi]
and rcx, -32
xor edx, edx
pcmpeqd xmm0, xmm0Metadata
Metadata
Assignees
Labels
A-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.C-bugCategory: This is a bug.Category: This is a bug.P-mediumMedium priorityMedium priorityS-has-bisectionStatus: A bisection has been found for this issueStatus: A bisection has been found for this issueT-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.regression-from-stable-to-stablePerformance or correctness regression from one stable version to another.Performance or correctness regression from one stable version to another.regression-untriagedUntriaged performance or correctness regression.Untriaged performance or correctness regression.
Activity
nikic commentedon Dec 5, 2025
Could you please clarify what regression you're referring to? Is this about the replacement of the
and -8with a larger immediate or something else?CrazyboyQCD commentedon Dec 5, 2025
Sure, regression part is added.
SpriteOvO commentedon Jan 22, 2026
Bisection points to #148350.
apiraino commentedon Jan 29, 2026
In #148350 I see a discussion about the perf. results (in the end accepted), I don't know if this issue is relevant to that.
cc @davidtwco @JonathanBrouwer @scottmcm
thanks
JonathanBrouwer commentedon Jan 30, 2026
This is the difference in the generated LLVM IR with and without this optimization, generated using:
For the following code
On the left without the change from the PR, on the right with the change from the PR (current develop)
https://www.diffchecker.com/TH7c8YwH/
I am not that experienced reading LLVM IR, but to me it seems like the new code has more hints for LLVM, other than that the are no differences
JonathanBrouwer commentedon Jan 30, 2026
Actually it might be that the
andinstruction generated optimizes worse by LLVM.Without the change from the PR rust generates an
ANDwith0xFFFFFFFFFFFFFFF8, with the change from the PR rust generates anANDwith1FFFFFFFFFFFFFF8. Both are correct (because the leading bits are always zero), but the second is not optimized as well by LLVMJonathanBrouwer commentedon Jan 30, 2026
Not entirely sure what to do with this observation, I guess we can consider reverting the original PR since it didn't have a significant perf win anyways?
apiraino commentedon Feb 5, 2026
Assigning priority (discussion on Zulip).
@rustbot label -I-prioritize +P-medium +regression-from-stable-to-beta
scottmcm commentedon Feb 5, 2026
If you look at what we actually give to LLVM https://godbolt.org/z/9ddzW74s4 (rather than the post-optimization IR), you'll see that the only meaningful difference is having the
range(i64 0, 2305843009213693952)attribute on%data.1.Any change to the constant being
anded is entirely something that LLVM did, so I think this should just be reported to LLVM. (Obviously it's not intentionally producing worse output given a more-constrained input.)Also, importantly note that this difference isn't in the loop body. It's just a couple pipelined instructions in the preheader for vectorization. If the slice is shorter than 8, the section with the difference doesn't run. And if it's 8-or-more, the inner loop is still
so IMHO this would be more P-low, not even P-medium, unless people can show more concrete impact from it.
I don't think we should revert it because that also loses the places where LLVM takes better advantage of the parameter range, like in getting more
samesignandnswflags on other instructions that then enable other downstream optimizations.(If this was impact to the inner loop, or to ever indexing, or something then I'd be far more worried, but here I'm not and it's just something for LLVM to eventually handle in a smarter way.)
el-ev commentedon May 10, 2026
Upstream: llvm/llvm-project#196786
@rustbot claim