diff --git a/src/test/codegen/comparison-operators-twofields.rs b/src/test/codegen/comparison-operators-twofields.rs new file mode 100644 index 00000000000..991bcc91c03 --- /dev/null +++ b/src/test/codegen/comparison-operators-twofields.rs @@ -0,0 +1,62 @@ +// The `derive(PartialOrd)` for structs doesn't override `lt`/`le`/`gt`/`ge`. +// This double-checks that the `Option` intermediate values used +// in the operators for such a type all optimize away, leaving just the +// necessary primitive comparisons. + +// compile-flags: -C opt-level=1 +// min-llvm-version: 15.0 + +#![crate_type = "lib"] + +use std::cmp::Ordering; + +#[derive(PartialOrd, PartialEq)] +pub struct Bar(i16, u16); + +// CHECK-LABEL: @check_lt +// CHECK-SAME: (i16 %[[A0:.+]], i16 %[[A1:.+]], i16 %[[B0:.+]], i16 %[[B1:.+]]) +#[no_mangle] +pub fn check_lt(a: Bar, b: Bar) -> bool { + // CHECK-DAG: %[[EQ:.+]] = icmp eq i16 %[[A0]], %[[B0]] + // CHECK-DAG: %[[CMP0:.+]] = icmp slt i16 %[[A0]], %[[B0]] + // CHECK-DAG: %[[CMP1:.+]] = icmp ult i16 %[[A1]], %[[B1]] + // CHECK: %[[R:.+]] = select i1 %[[EQ]], i1 %[[CMP1]], i1 %[[CMP0]] + // CHECK: ret i1 %[[R]] + a < b +} + +// CHECK-LABEL: @check_le +// CHECK-SAME: (i16 %[[A0:.+]], i16 %[[A1:.+]], i16 %[[B0:.+]], i16 %[[B1:.+]]) +#[no_mangle] +pub fn check_le(a: Bar, b: Bar) -> bool { + // CHECK-DAG: %[[EQ:.+]] = icmp eq i16 %[[A0]], %[[B0]] + // CHECK-DAG: %[[CMP0:.+]] = icmp sle i16 %[[A0]], %[[B0]] + // CHECK-DAG: %[[CMP1:.+]] = icmp ule i16 %[[A1]], %[[B1]] + // CHECK: %[[R:.+]] = select i1 %[[EQ]], i1 %[[CMP1]], i1 %[[CMP0]] + // CHECK: ret i1 %[[R]] + a <= b +} + +// CHECK-LABEL: @check_gt +// CHECK-SAME: (i16 %[[A0:.+]], i16 %[[A1:.+]], i16 %[[B0:.+]], i16 %[[B1:.+]]) +#[no_mangle] +pub fn check_gt(a: Bar, b: Bar) -> bool { + // CHECK-DAG: %[[EQ:.+]] = icmp eq i16 %[[A0]], %[[B0]] + // CHECK-DAG: %[[CMP0:.+]] = icmp sgt i16 %[[A0]], %[[B0]] + // CHECK-DAG: %[[CMP1:.+]] = icmp ugt i16 %[[A1]], %[[B1]] + // CHECK: %[[R:.+]] = select i1 %[[EQ]], i1 %[[CMP1]], i1 %[[CMP0]] + // CHECK: ret i1 %[[R]] + a > b +} + +// CHECK-LABEL: @check_ge +// CHECK-SAME: (i16 %[[A0:.+]], i16 %[[A1:.+]], i16 %[[B0:.+]], i16 %[[B1:.+]]) +#[no_mangle] +pub fn check_ge(a: Bar, b: Bar) -> bool { + // CHECK-DAG: %[[EQ:.+]] = icmp eq i16 %[[A0]], %[[B0]] + // CHECK-DAG: %[[CMP0:.+]] = icmp sge i16 %[[A0]], %[[B0]] + // CHECK-DAG: %[[CMP1:.+]] = icmp uge i16 %[[A1]], %[[B1]] + // CHECK: %[[R:.+]] = select i1 %[[EQ]], i1 %[[CMP1]], i1 %[[CMP0]] + // CHECK: ret i1 %[[R]] + a >= b +}