-
Notifications
You must be signed in to change notification settings - Fork 13.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Use the chaining methods on PartialOrd for slices too #138881
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,7 @@ | ||
// Ensure the asm for array comparisons is properly optimized. | ||
|
||
//@ compile-flags: -C opt-level=2 | ||
//@ needs-deterministic-layouts (checks depend on tuple layout) | ||
|
||
#![crate_type = "lib"] | ||
|
||
|
@@ -17,3 +18,57 @@ pub fn compare() -> bool { | |
[0x00, 0x00, 0x48, 0x41] | ||
} | ||
} | ||
|
||
// CHECK-LABEL: @array_of_tuple_le | ||
#[no_mangle] | ||
pub fn array_of_tuple_le(a: &[(i16, u16); 2], b: &[(i16, u16); 2]) -> bool { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nightly, note the array_of_tuple_le:
movzwl (%rdi), %eax
movzwl (%rsi), %ecx
cmpw %cx, %ax
setl %cl
setg %al
jne .LBB0_1
movzwl 2(%rdi), %eax
cmpw 2(%rsi), %ax
seta %al
sbbb $0, %al
testb %al, %al
jne .LBB0_7
jmp .LBB0_4
.LBB0_1:
subb %cl, %al
testb %al, %al
jne .LBB0_7
.LBB0_4:
movzwl 4(%rdi), %eax
movzwl 4(%rsi), %ecx
cmpw %cx, %ax
setl %cl
setg %al
jne .LBB0_5
movzwl 6(%rdi), %eax
cmpw 6(%rsi), %ax
seta %al
sbbb $0, %al
jmp .LBB0_7
.LBB0_5:
subb %cl, %al
.LBB0_7:
testb %al, %al
setle %al
retq With this PR: array_of_tuple_le:
movzwl (%rcx), %eax
movzwl (%rdx), %r8d
cmpw %r8w, %ax
jne .LBB1_1
movzwl 2(%rcx), %r8d
movzwl 2(%rdx), %r9d
cmpw %r9w, %r8w
jne .LBB1_2
movzwl 4(%rcx), %eax
movzwl 4(%rdx), %r8d
cmpw %r8w, %ax
jne .LBB1_1
movzwl 6(%rcx), %r8d
movzwl 6(%rdx), %r9d
movb $1, %al
cmpw %r9w, %r8w
jne .LBB1_2
retq
.LBB1_1:
cmpw %r8w, %ax
setle %al
retq
.LBB1_2:
cmpw %r9w, %r8w
setb %al
retq That's so nice -- straight line with no jumps taken if they're equal, otherwise jumps to the check it needs (dedup'd by consistent register choices), saves that, and returns. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Note that even with #133984 landed, we still don't optimize away the |
||
// Ensure that, after all the optimizations have run, the happy path just checks | ||
// `eq` on each corresponding pair and moves onto the next one if it is. | ||
// Then there's a dedup'd comparison for the place that's different. | ||
// (As opposed to, say, running a full `[su]cmp` as part of checking equality.) | ||
|
||
// This is written quite specifically because different library code was triggering | ||
// <https://github.com/llvm/llvm-project/issues/132678> along the way, so this | ||
// has enough checks to make sure that's not happening. It doesn't need to be | ||
// *exactly* this IR, but be careful if you ever need to update these checks. | ||
|
||
// CHECK: start: | ||
// CHECK: %[[A00:.+]] = load i16, ptr %a | ||
// CHECK: %[[B00:.+]] = load i16, ptr %b | ||
// CHECK-NOT: cmp | ||
// CHECK: %[[EQ00:.+]] = icmp eq i16 %[[A00]], %[[B00]] | ||
// CHECK-NEXT: br i1 %[[EQ00]], label %[[L01:.+]], label %[[EXIT_S:.+]] | ||
|
||
// CHECK: [[L01]]: | ||
// CHECK: %[[PA01:.+]] = getelementptr{{.+}}i8, ptr %a, i64 2 | ||
// CHECK: %[[PB01:.+]] = getelementptr{{.+}}i8, ptr %b, i64 2 | ||
// CHECK: %[[A01:.+]] = load i16, ptr %[[PA01]] | ||
// CHECK: %[[B01:.+]] = load i16, ptr %[[PB01]] | ||
// CHECK-NOT: cmp | ||
// CHECK: %[[EQ01:.+]] = icmp eq i16 %[[A01]], %[[B01]] | ||
// CHECK-NEXT: br i1 %[[EQ01]], label %[[L10:.+]], label %[[EXIT_U:.+]] | ||
|
||
// CHECK: [[L10]]: | ||
// CHECK: %[[PA10:.+]] = getelementptr{{.+}}i8, ptr %a, i64 4 | ||
// CHECK: %[[PB10:.+]] = getelementptr{{.+}}i8, ptr %b, i64 4 | ||
// CHECK: %[[A10:.+]] = load i16, ptr %[[PA10]] | ||
// CHECK: %[[B10:.+]] = load i16, ptr %[[PB10]] | ||
// CHECK-NOT: cmp | ||
// CHECK: %[[EQ10:.+]] = icmp eq i16 %[[A10]], %[[B10]] | ||
// CHECK-NEXT: br i1 %[[EQ10]], label %[[L11:.+]], label %[[EXIT_S]] | ||
|
||
// CHECK: [[L11]]: | ||
// CHECK: %[[PA11:.+]] = getelementptr{{.+}}i8, ptr %a, i64 6 | ||
// CHECK: %[[PB11:.+]] = getelementptr{{.+}}i8, ptr %b, i64 6 | ||
// CHECK: %[[A11:.+]] = load i16, ptr %[[PA11]] | ||
// CHECK: %[[B11:.+]] = load i16, ptr %[[PB11]] | ||
// CHECK-NOT: cmp | ||
// CHECK: %[[EQ11:.+]] = icmp eq i16 %[[A11]], %[[B11]] | ||
// CHECK-NEXT: br i1 %[[EQ11]], label %[[DONE:.+]], label %[[EXIT_U]] | ||
|
||
// CHECK: [[DONE]]: | ||
// CHECK: %[[RET:.+]] = phi i1 [ %{{.+}}, %[[EXIT_S]] ], [ %{{.+}}, %[[EXIT_U]] ], [ true, %[[L11]] ] | ||
// CHECK: ret i1 %[[RET]] | ||
|
||
a <= b | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So there's a backlink: llvm/llvm-project#132678