jiebi/CodeConvo huggingface dataset:
Code change:
From a recent Reddit discussion ( ): Gives (rustc 1.53.0-nightly 2021-03-26): That Reddit discussion shows other cases.
See also:
I am quite surprised but fix of doesn't fix this issue. <details<summaryASM </summary</details
With the last nightly I'm seeing a probable improvement in foo1b (the second):
It looks like that one of SROA passes transforms getting of tuple fields into nearly this: Edit: Removing SROA doesn't prevent this transformation, it just happens in other steps.
This leads to big overhead of tuples and structs (because tuples is structs). Benchmark Results: So, PartialEq slower from 4 to 40 times.
Hack We could change std using this weird trick but possibly shouldn't. <details<summaryHacky code</summary</detailsThe problem is that we still: 't fix situation for structs (actually, problem affects every struct which size less or equal to 8 bytes) 't fix situation with tuples like or (newtypeoveru8, u8, ...) With the last nightly I'm seeing a probable improvement in foo1b (the second): Unfortunately, and inlining would convert this function to case. I suggest you to rename the issue to something like "Small POD struct equality ineffective".
It looks like Clang incapable for making such optimizations as well.
On the LLVM side, we're basically missing this fold:
Upstream review:
Upstream fix:
I ran into an issue where using a struct of two arrays was significant slower than passing those arrays directly. My arrays were larger, but the struct also came with a large overhead. Could those issues be related?
Unfortunately this has not been fixed by the LLVM 13 upgrade. Might be an unfortunate interaction with the migration from bitwise to logical and.
Upstream fix for the logical and/or issue: , Might make sense to cherry-pick this to our fork to avoid waiting another release cycle.
For the case foo1b the MergeICmps pass would usually handle this in the backend, but it's getting blocked by additional calls.
We're now generating good code for everything but foo1b: foo1b still unnecessarily splits out one comparison. Either or should address that.
Remaining case is fixed by the LLVM upgrade in Adding a codegen test for this may be worthwhile.
Thats true for , for it's still the same.

Related discussion:
text: <ins> //@ compile-flags: -O //@ min-llvm-version: 17 #![crate_type = "lib"] #[no_mangle] // CHECK-LABEL: @foo // CHECK: getelementptr inbounds // CHECK-NEXT: load i64 // CHECK-NEXT: icmp eq i64 // CHECK-NEXT: br i1 #[no_mangle] pub fn foo(input: &mut &[u64]) -> Option<u64> { let (first, rest) = input.split_first()?; *input = rest; Some(*first) } </ins>
Code change:
From a recent Reddit discussion ( ): Gives (rustc 1.53.0-nightly 2021-03-26): That Reddit discussion shows other cases.
See also:
I am quite surprised but fix of doesn't fix this issue. <details<summaryASM </summary</details
With the last nightly I'm seeing a probable improvement in foo1b (the second):
It looks like that one of SROA passes transforms getting of tuple fields into nearly this: Edit: Removing SROA doesn't prevent this transformation, it just happens in other steps.
This leads to big overhead of tuples and structs (because tuples is structs). Benchmark Results: So, PartialEq slower from 4 to 40 times.
Hack We could change std using this weird trick but possibly shouldn't. <details<summaryHacky code</summary</detailsThe problem is that we still: 't fix situation for structs (actually, problem affects every struct which size less or equal to 8 bytes) 't fix situation with tuples like or (newtypeoveru8, u8, ...) With the last nightly I'm seeing a probable improvement in foo1b (the second): Unfortunately, and inlining would convert this function to case. I suggest you to rename the issue to something like "Small POD struct equality ineffective".
It looks like Clang incapable for making such optimizations as well.
On the LLVM side, we're basically missing this fold:
Upstream review:
Upstream fix:
I ran into an issue where using a struct of two arrays was significant slower than passing those arrays directly. My arrays were larger, but the struct also came with a large overhead. Could those issues be related?
Unfortunately this has not been fixed by the LLVM 13 upgrade. Might be an unfortunate interaction with the migration from bitwise to logical and.
Upstream fix for the logical and/or issue: , Might make sense to cherry-pick this to our fork to avoid waiting another release cycle.
For the case foo1b the MergeICmps pass would usually handle this in the backend, but it's getting blocked by additional calls.
We're now generating good code for everything but foo1b: foo1b still unnecessarily splits out one comparison. Either or should address that.
Remaining case is fixed by the LLVM upgrade in Adding a codegen test for this may be worthwhile.
Thats true for , for it's still the same.

Related discussion:
text: <ins> //@ compile-flags: -O // XXX: The x86-64 assembly get optimized correclty. But llvm-ir output is not until llvm 18? //@ min-llvm-version: 18 #![crate_type = "lib"] pub enum K{ A(Box<[i32]>), B(Box<[u8]>), C(Box<[String]>), D(Box<[u16]>), } #[no_mangle] // CHECK-LABEL: @get_len // CHECK: getelementptr inbounds // CHECK-NEXT: load // CHECK-NEXT: ret i64 // CHECK-NOT: switch pub fn get_len(arg: &K)->usize{ match arg { K::A(ref lst)=>lst.len(), K::B(ref lst)=>lst.len(), K::C(ref lst)=>lst.len(), K::D(ref lst)=>lst.len(), } } </ins>
Code change:
From a recent Reddit discussion ( ): Gives (rustc 1.53.0-nightly 2021-03-26): That Reddit discussion shows other cases.
See also:
I am quite surprised but fix of doesn't fix this issue. <details<summaryASM </summary</details
With the last nightly I'm seeing a probable improvement in foo1b (the second):
It looks like that one of SROA passes transforms getting of tuple fields into nearly this: Edit: Removing SROA doesn't prevent this transformation, it just happens in other steps.
This leads to big overhead of tuples and structs (because tuples is structs). Benchmark Results: So, PartialEq slower from 4 to 40 times.
Hack We could change std using this weird trick but possibly shouldn't. <details<summaryHacky code</summary</detailsThe problem is that we still: 't fix situation for structs (actually, problem affects every struct which size less or equal to 8 bytes) 't fix situation with tuples like or (newtypeoveru8, u8, ...) With the last nightly I'm seeing a probable improvement in foo1b (the second): Unfortunately, and inlining would convert this function to case. I suggest you to rename the issue to something like "Small POD struct equality ineffective".
It looks like Clang incapable for making such optimizations as well.
On the LLVM side, we're basically missing this fold:
Upstream review:
Upstream fix:
I ran into an issue where using a struct of two arrays was significant slower than passing those arrays directly. My arrays were larger, but the struct also came with a large overhead. Could those issues be related?
Unfortunately this has not been fixed by the LLVM 13 upgrade. Might be an unfortunate interaction with the migration from bitwise to logical and.
Upstream fix for the logical and/or issue: , Might make sense to cherry-pick this to our fork to avoid waiting another release cycle.
For the case foo1b the MergeICmps pass would usually handle this in the backend, but it's getting blocked by additional calls.
We're now generating good code for everything but foo1b: foo1b still unnecessarily splits out one comparison. Either or should address that.
Remaining case is fixed by the LLVM upgrade in Adding a codegen test for this may be worthwhile.
Thats true for , for it's still the same.

Related discussion:
text: <ins> //@ compile-flags: -O // This regress since Rust version 1.72. //@ min-llvm-version: 18.1.4 #![crate_type = "lib"] use std::convert::TryInto; const N: usize = 24; #[no_mangle] // CHECK-LABEL: @example // CHECK-NOT: unwrap_failed pub fn example(a: Vec<u8>) -> u8 { if a.len() != 32 { return 0; } let a: [u8; 32] = a.try_into().unwrap(); a[15] + a[N] } </ins>
Code change:
From a recent Reddit discussion ( ): Gives (rustc 1.53.0-nightly 2021-03-26): That Reddit discussion shows other cases.
See also:
I am quite surprised but fix of doesn't fix this issue. <details<summaryASM </summary</details
With the last nightly I'm seeing a probable improvement in foo1b (the second):
It looks like that one of SROA passes transforms getting of tuple fields into nearly this: Edit: Removing SROA doesn't prevent this transformation, it just happens in other steps.
This leads to big overhead of tuples and structs (because tuples is structs). Benchmark Results: So, PartialEq slower from 4 to 40 times.
Hack We could change std using this weird trick but possibly shouldn't. <details<summaryHacky code</summary</detailsThe problem is that we still: 't fix situation for structs (actually, problem affects every struct which size less or equal to 8 bytes) 't fix situation with tuples like or (newtypeoveru8, u8, ...) With the last nightly I'm seeing a probable improvement in foo1b (the second): Unfortunately, and inlining would convert this function to case. I suggest you to rename the issue to something like "Small POD struct equality ineffective".
It looks like Clang incapable for making such optimizations as well.
On the LLVM side, we're basically missing this fold:
Upstream review:
Upstream fix:
I ran into an issue where using a struct of two arrays was significant slower than passing those arrays directly. My arrays were larger, but the struct also came with a large overhead. Could those issues be related?
Unfortunately this has not been fixed by the LLVM 13 upgrade. Might be an unfortunate interaction with the migration from bitwise to logical and.
Upstream fix for the logical and/or issue: , Might make sense to cherry-pick this to our fork to avoid waiting another release cycle.
For the case foo1b the MergeICmps pass would usually handle this in the backend, but it's getting blocked by additional calls.
We're now generating good code for everything but foo1b: foo1b still unnecessarily splits out one comparison. Either or should address that.
Remaining case is fixed by the LLVM upgrade in Adding a codegen test for this may be worthwhile.
Thats true for , for it's still the same.

Related discussion:
text: <ins> //@ compile-flags: -O //@ min-llvm-version: 17 #![crate_type = "lib"] // CHECK-LABEL: @write_u8_variant_a // CHECK: getelementptr // CHECK-NEXT: icmp ugt #[no_mangle] pub fn write_u8_variant_a( bytes: &mut [u8], buf: u8, offset: usize, ) -> Option<&mut [u8]> { let buf = buf.to_le_bytes(); bytes .get_mut(offset..).and_then(|bytes| bytes.get_mut(..buf.len())) } </ins>
Code change:
From a recent Reddit discussion ( ): Gives (rustc 1.53.0-nightly 2021-03-26): That Reddit discussion shows other cases.
See also:
I am quite surprised but fix of doesn't fix this issue. <details<summaryASM </summary</details
With the last nightly I'm seeing a probable improvement in foo1b (the second):
It looks like that one of SROA passes transforms getting of tuple fields into nearly this: Edit: Removing SROA doesn't prevent this transformation, it just happens in other steps.
This leads to big overhead of tuples and structs (because tuples is structs). Benchmark Results: So, PartialEq slower from 4 to 40 times.
Hack We could change std using this weird trick but possibly shouldn't. <details<summaryHacky code</summary</detailsThe problem is that we still: 't fix situation for structs (actually, problem affects every struct which size less or equal to 8 bytes) 't fix situation with tuples like or (newtypeoveru8, u8, ...) With the last nightly I'm seeing a probable improvement in foo1b (the second): Unfortunately, and inlining would convert this function to case. I suggest you to rename the issue to something like "Small POD struct equality ineffective".
It looks like Clang incapable for making such optimizations as well.
On the LLVM side, we're basically missing this fold:
Upstream review:
Upstream fix:
I ran into an issue where using a struct of two arrays was significant slower than passing those arrays directly. My arrays were larger, but the struct also came with a large overhead. Could those issues be related?
Unfortunately this has not been fixed by the LLVM 13 upgrade. Might be an unfortunate interaction with the migration from bitwise to logical and.
Upstream fix for the logical and/or issue: , Might make sense to cherry-pick this to our fork to avoid waiting another release cycle.
For the case foo1b the MergeICmps pass would usually handle this in the backend, but it's getting blocked by additional calls.
We're now generating good code for everything but foo1b: foo1b still unnecessarily splits out one comparison. Either or should address that.
Remaining case is fixed by the LLVM upgrade in Adding a codegen test for this may be worthwhile.
Thats true for , for it's still the same.

Related discussion:
text: <ins> // in Rust 1.73, -O and opt-level=3 optimizes differently //@ compile-flags: -C opt-level=3 //@ min-llvm-version: 17 #![crate_type = "lib"] use std::cmp::max; #[no_mangle] // CHECK-LABEL: @foo // CHECK-NOT: slice_start_index_len_fail // CHECK-NOT: unreachable pub fn foo(v: &mut Vec<u8>, size: usize)-> Option<&mut [u8]> { if v.len() > max(1, size) { let start = v.len() - size; Some(&mut v[start..]) } else { None } } </ins>
Code change:
From a recent Reddit discussion ( ): Gives (rustc 1.53.0-nightly 2021-03-26): That Reddit discussion shows other cases.
See also:
I am quite surprised but fix of doesn't fix this issue. <details<summaryASM </summary</details
With the last nightly I'm seeing a probable improvement in foo1b (the second):
It looks like that one of SROA passes transforms getting of tuple fields into nearly this: Edit: Removing SROA doesn't prevent this transformation, it just happens in other steps.
This leads to big overhead of tuples and structs (because tuples is structs). Benchmark Results: So, PartialEq slower from 4 to 40 times.
Hack We could change std using this weird trick but possibly shouldn't. <details<summaryHacky code</summary</detailsThe problem is that we still: 't fix situation for structs (actually, problem affects every struct which size less or equal to 8 bytes) 't fix situation with tuples like or (newtypeoveru8, u8, ...) With the last nightly I'm seeing a probable improvement in foo1b (the second): Unfortunately, and inlining would convert this function to case. I suggest you to rename the issue to something like "Small POD struct equality ineffective".
It looks like Clang incapable for making such optimizations as well.
On the LLVM side, we're basically missing this fold:
Upstream review:
Upstream fix:
I ran into an issue where using a struct of two arrays was significant slower than passing those arrays directly. My arrays were larger, but the struct also came with a large overhead. Could those issues be related?
Unfortunately this has not been fixed by the LLVM 13 upgrade. Might be an unfortunate interaction with the migration from bitwise to logical and.
Upstream fix for the logical and/or issue: , Might make sense to cherry-pick this to our fork to avoid waiting another release cycle.
For the case foo1b the MergeICmps pass would usually handle this in the backend, but it's getting blocked by additional calls.
We're now generating good code for everything but foo1b: foo1b still unnecessarily splits out one comparison. Either or should address that.
Remaining case is fixed by the LLVM upgrade in Adding a codegen test for this may be worthwhile.
Thats true for , for it's still the same.

Related discussion:
text: <ins> //@ compile-flags: -O //@ min-llvm-version: 18 #![crate_type = "lib"] // CHECK-LABEL: @div2 // CHECK: ashr i32 %a, 1 // CHECK-NEXT: ret i32 #[no_mangle] pub fn div2(a: i32) -> i32 { a.div_euclid(2) } </ins>
Code change:
From a recent Reddit discussion ( ): Gives (rustc 1.53.0-nightly 2021-03-26): That Reddit discussion shows other cases.
See also:
I am quite surprised but fix of doesn't fix this issue. <details<summaryASM </summary</details
With the last nightly I'm seeing a probable improvement in foo1b (the second):
It looks like that one of SROA passes transforms getting of tuple fields into nearly this: Edit: Removing SROA doesn't prevent this transformation, it just happens in other steps.
This leads to big overhead of tuples and structs (because tuples is structs). Benchmark Results: So, PartialEq slower from 4 to 40 times.
Hack We could change std using this weird trick but possibly shouldn't. <details<summaryHacky code</summary</detailsThe problem is that we still: 't fix situation for structs (actually, problem affects every struct which size less or equal to 8 bytes) 't fix situation with tuples like or (newtypeoveru8, u8, ...) With the last nightly I'm seeing a probable improvement in foo1b (the second): Unfortunately, and inlining would convert this function to case. I suggest you to rename the issue to something like "Small POD struct equality ineffective".
It looks like Clang incapable for making such optimizations as well.
On the LLVM side, we're basically missing this fold:
Upstream review:
Upstream fix:
I ran into an issue where using a struct of two arrays was significant slower than passing those arrays directly. My arrays were larger, but the struct also came with a large overhead. Could those issues be related?
Unfortunately this has not been fixed by the LLVM 13 upgrade. Might be an unfortunate interaction with the migration from bitwise to logical and.
Upstream fix for the logical and/or issue: , Might make sense to cherry-pick this to our fork to avoid waiting another release cycle.
For the case foo1b the MergeICmps pass would usually handle this in the backend, but it's getting blocked by additional calls.
We're now generating good code for everything but foo1b: foo1b still unnecessarily splits out one comparison. Either or should address that.
Remaining case is fixed by the LLVM upgrade in Adding a codegen test for this may be worthwhile.
Thats true for , for it's still the same.

Related discussion:
text: <ins> //@ compile-flags: -O #![crate_type = "lib"] const N: usize = 3; pub type T = u8; #[no_mangle] // CHECK-LABEL: @split_mutiple // CHECK-NOT: unreachable pub fn split_mutiple(slice: &[T]) -> (&[T], &[T]) { let len = slice.len() / N; slice.split_at(len * N) } </ins>
Code change:
From a recent Reddit discussion ( ): Gives (rustc 1.53.0-nightly 2021-03-26): That Reddit discussion shows other cases.
See also:
I am quite surprised but fix of doesn't fix this issue. <details<summaryASM </summary</details
With the last nightly I'm seeing a probable improvement in foo1b (the second):
It looks like that one of SROA passes transforms getting of tuple fields into nearly this: Edit: Removing SROA doesn't prevent this transformation, it just happens in other steps.
This leads to big overhead of tuples and structs (because tuples is structs). Benchmark Results: So, PartialEq slower from 4 to 40 times.
Hack We could change std using this weird trick but possibly shouldn't. <details<summaryHacky code</summary</detailsThe problem is that we still: 't fix situation for structs (actually, problem affects every struct which size less or equal to 8 bytes) 't fix situation with tuples like or (newtypeoveru8, u8, ...) With the last nightly I'm seeing a probable improvement in foo1b (the second): Unfortunately, and inlining would convert this function to case. I suggest you to rename the issue to something like "Small POD struct equality ineffective".
It looks like Clang incapable for making such optimizations as well.
On the LLVM side, we're basically missing this fold:
Upstream review:
Upstream fix:
I ran into an issue where using a struct of two arrays was significant slower than passing those arrays directly. My arrays were larger, but the struct also came with a large overhead. Could those issues be related?
Unfortunately this has not been fixed by the LLVM 13 upgrade. Might be an unfortunate interaction with the migration from bitwise to logical and.
Upstream fix for the logical and/or issue: , Might make sense to cherry-pick this to our fork to avoid waiting another release cycle.
For the case foo1b the MergeICmps pass would usually handle this in the backend, but it's getting blocked by additional calls.
We're now generating good code for everything but foo1b: foo1b still unnecessarily splits out one comparison. Either or should address that.
Remaining case is fixed by the LLVM upgrade in Adding a codegen test for this may be worthwhile.
Thats true for , for it's still the same.

Related discussion:
text: <ins> //@ compile-flags: -O //@ min-llvm-version: 17 #![crate_type = "lib"] #[no_mangle] // CHECK-LABEL: @foo // CHECK: {{.*}}: // CHECK: ret // CHECK-NOT: unreachable pub fn foo(arr: &mut [u32]) { for i in 0..arr.len() { for j in 0..i { assert!(j < arr.len()); } } } </ins>
Code change:
From a recent Reddit discussion ( ): Gives (rustc 1.53.0-nightly 2021-03-26): That Reddit discussion shows other cases.
See also:
I am quite surprised but fix of doesn't fix this issue. <details<summaryASM </summary</details
With the last nightly I'm seeing a probable improvement in foo1b (the second):
It looks like that one of SROA passes transforms getting of tuple fields into nearly this: Edit: Removing SROA doesn't prevent this transformation, it just happens in other steps.
This leads to big overhead of tuples and structs (because tuples is structs). Benchmark Results: So, PartialEq slower from 4 to 40 times.
Hack We could change std using this weird trick but possibly shouldn't. <details<summaryHacky code</summary</detailsThe problem is that we still: 't fix situation for structs (actually, problem affects every struct which size less or equal to 8 bytes) 't fix situation with tuples like or (newtypeoveru8, u8, ...) With the last nightly I'm seeing a probable improvement in foo1b (the second): Unfortunately, and inlining would convert this function to case. I suggest you to rename the issue to something like "Small POD struct equality ineffective".
It looks like Clang incapable for making such optimizations as well.
On the LLVM side, we're basically missing this fold:
Upstream review:
Upstream fix:
I ran into an issue where using a struct of two arrays was significant slower than passing those arrays directly. My arrays were larger, but the struct also came with a large overhead. Could those issues be related?
Unfortunately this has not been fixed by the LLVM 13 upgrade. Might be an unfortunate interaction with the migration from bitwise to logical and.
Upstream fix for the logical and/or issue: , Might make sense to cherry-pick this to our fork to avoid waiting another release cycle.
For the case foo1b the MergeICmps pass would usually handle this in the backend, but it's getting blocked by additional calls.
We're now generating good code for everything but foo1b: foo1b still unnecessarily splits out one comparison. Either or should address that.
Remaining case is fixed by the LLVM upgrade in Adding a codegen test for this may be worthwhile.
Thats true for , for it's still the same.

Related discussion:
text: <ins> //@ compile-flags: -O //@ min-llvm-version: 18 #![crate_type = "lib"] use std::ptr::NonNull; // CHECK-LABEL: @slice_ptr_len_1 // CHECK: {{.*}}: // CHECK-NEXT: ret i64 %ptr.1 #[no_mangle] pub fn slice_ptr_len_1(ptr: *const [u8]) -> usize { let ptr = ptr.cast_mut(); if let Some(ptr) = NonNull::new(ptr) { ptr.len() } else { // We know ptr is null, so we know ptr.wrapping_byte_add(1) is not null. NonNull::new(ptr.wrapping_byte_add(1)).unwrap().len() } } </ins>