diff options
| author | Scott McMurray <scottmcm@users.noreply.github.com> | 2025-03-23 20:45:36 -0700 | 
|---|---|---|
| committer | Scott McMurray <scottmcm@users.noreply.github.com> | 2025-04-12 22:10:17 -0700 | 
| commit | 756670f40ebedd4a6cb1ebf356cb327442888d0a (patch) | |
| tree | 645829fe0c0709d0500f68ab4610b192dcd2f357 /tests/codegen/array-cmp.rs | |
| parent | 19648ce5cd12b11889eccacac50c70ca8ac78fee (diff) | |
| download | rust-756670f40ebedd4a6cb1ebf356cb327442888d0a.tar.gz rust-756670f40ebedd4a6cb1ebf356cb327442888d0a.zip | |
Extend the chaining logic to slices too
Diffstat (limited to 'tests/codegen/array-cmp.rs')
| -rw-r--r-- | tests/codegen/array-cmp.rs | 55 | 
1 files changed, 49 insertions, 6 deletions
| diff --git a/tests/codegen/array-cmp.rs b/tests/codegen/array-cmp.rs index f9b7be89882..0d337655401 100644 --- a/tests/codegen/array-cmp.rs +++ b/tests/codegen/array-cmp.rs @@ -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"] @@ -19,13 +20,55 @@ pub fn compare() -> bool { } // CHECK-LABEL: @array_of_tuple_le -// CHECK: call{{.+}}i8 @llvm.scmp.i8.i16 -// CHECK: call{{.+}}i8 @llvm.ucmp.i8.i16 -// CHECK: call{{.+}}i8 @llvm.scmp.i8.i16 -// CHECK: call{{.+}}i8 @llvm.ucmp.i8.i16 -// CHECK: %[[RET:.+]] = icmp slt i8 {{.+}}, 1 -// CHECK: ret i8 %[[RET]] #[no_mangle] pub fn array_of_tuple_le(a: &[(i16, u16); 2], b: &[(i16, u16); 2]) -> bool { + // 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, {{i32|i64}} 2 + // CHECK: %[[PB01:.+]] = getelementptr{{.+}}i8, ptr %b, {{i32|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, {{i32|i64}} 4 + // CHECK: %[[PB10:.+]] = getelementptr{{.+}}i8, ptr %b, {{i32|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, {{i32|i64}} 6 + // CHECK: %[[PB11:.+]] = getelementptr{{.+}}i8, ptr %b, {{i32|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 } | 
