blob: ef6bb5556e225126525e5b54e745d3d87b0db025 [file] [log] [blame]
Eric Fiselier0683c0e2018-05-07 21:07:10 +00001// RUN: %clang_cc1 -std=c++2a -emit-llvm %s -o - -triple %itanium_abi_triple | \
2// RUN: FileCheck %s \
3// RUN: '-DWE="class.std::__1::weak_equality"' \
4// RUN: '-DSO="class.std::__1::strong_ordering"' \
5// RUN: '-DSE="class.std::__1::strong_equality"' \
6// RUN: '-DPO="class.std::__1::partial_ordering"' \
7// RUN: -DEQ=0 -DLT=-1 -DGT=1 -DUNORD=-127 -DNE=1
8
9#include "Inputs/std-compare.h"
10
11// Ensure we don't emit definitions for the global variables
12// since the builtins shouldn't ODR use them.
13// CHECK-NOT: constant %[[SO]]
14// CHECK-NOT: constant %[[SE]]
15// CHECK-NOT: constant %[[WE]]
16// CHECK-NOT: constant %[[PO]]
17
18// CHECK-LABEL: @_Z11test_signedii
19auto test_signed(int x, int y) {
Eric Fiselier2ab957e2018-05-07 23:15:34 +000020 // CHECK: %[[DEST:retval|agg.result]]
Eric Fiselier0683c0e2018-05-07 21:07:10 +000021 // CHECK: %cmp.lt = icmp slt i32 %0, %1
22 // CHECK: %sel.lt = select i1 %cmp.lt, i8 [[LT]], i8 [[GT]]
23 // CHECK: %cmp.eq = icmp eq i32 %0, %1
24 // CHECK: %sel.eq = select i1 %cmp.eq, i8 [[EQ]], i8 %sel.lt
Eric Fiselier2ab957e2018-05-07 23:15:34 +000025 // CHECK: %__value_ = getelementptr inbounds %[[SO]], %[[SO]]* %[[DEST]]
Eric Fiselier0683c0e2018-05-07 21:07:10 +000026 // CHECK: store i8 %sel.eq, i8* %__value_, align 1
Eric Fiselier2ab957e2018-05-07 23:15:34 +000027 // CHECK: ret
Eric Fiselier0683c0e2018-05-07 21:07:10 +000028 return x <=> y;
29}
30
31// CHECK-LABEL: @_Z13test_unsignedjj
32auto test_unsigned(unsigned x, unsigned y) {
Eric Fiselier2ab957e2018-05-07 23:15:34 +000033 // CHECK: %[[DEST:retval|agg.result]]
Eric Fiselier0683c0e2018-05-07 21:07:10 +000034 // CHECK: %cmp.lt = icmp ult i32 %0, %1
35 // CHECK: %sel.lt = select i1 %cmp.lt, i8 [[LT]], i8 [[GT]]
36 // CHECK: %cmp.eq = icmp eq i32 %0, %1
37 // CHECK: %sel.eq = select i1 %cmp.eq, i8 [[EQ]], i8 %sel.lt
Eric Fiselier2ab957e2018-05-07 23:15:34 +000038 // CHECK: %__value_ = getelementptr inbounds %[[SO]], %[[SO]]* %[[DEST]]
39 // CHECK: store i8 %sel.eq, i8* %__value_
Eric Fiselier0683c0e2018-05-07 21:07:10 +000040 // CHECK: ret
41 return x <=> y;
42}
43
44// CHECK-LABEL: @_Z10float_testdd
45auto float_test(double x, double y) {
Eric Fiselier2ab957e2018-05-07 23:15:34 +000046 // CHECK: %[[DEST:retval|agg.result]]
Eric Fiselier0683c0e2018-05-07 21:07:10 +000047 // CHECK: %cmp.eq = fcmp oeq double %0, %1
48 // CHECK: %sel.eq = select i1 %cmp.eq, i8 [[EQ]], i8 [[UNORD]]
49 // CHECK: %cmp.gt = fcmp ogt double %0, %1
50 // CHECK: %sel.gt = select i1 %cmp.gt, i8 [[GT]], i8 %sel.eq
51 // CHECK: %cmp.lt = fcmp olt double %0, %1
52 // CHECK: %sel.lt = select i1 %cmp.lt, i8 [[LT]], i8 %sel.gt
Eric Fiselier2ab957e2018-05-07 23:15:34 +000053 // CHECK: %__value_ = getelementptr inbounds %[[PO]], %[[PO]]* %[[DEST]]
54 // CHECK: store i8 %sel.lt, i8* %__value_
Eric Fiselier0683c0e2018-05-07 21:07:10 +000055 // CHECK: ret
56 return x <=> y;
57}
58
59// CHECK-LABEL: @_Z8ptr_testPiS_
60auto ptr_test(int *x, int *y) {
Eric Fiselier2ab957e2018-05-07 23:15:34 +000061 // CHECK: %[[DEST:retval|agg.result]]
Eric Fiselier0683c0e2018-05-07 21:07:10 +000062 // CHECK: %cmp.lt = icmp ult i32* %0, %1
63 // CHECK: %sel.lt = select i1 %cmp.lt, i8 [[LT]], i8 [[GT]]
64 // CHECK: %cmp.eq = icmp eq i32* %0, %1
65 // CHECK: %sel.eq = select i1 %cmp.eq, i8 [[EQ]], i8 %sel.lt
Eric Fiselier2ab957e2018-05-07 23:15:34 +000066 // CHECK: %__value_ = getelementptr inbounds %[[SO]], %[[SO]]* %[[DEST]]
67 // CHECK: store i8 %sel.eq, i8* %__value_, align 1
Eric Fiselier0683c0e2018-05-07 21:07:10 +000068 // CHECK: ret
69 return x <=> y;
70}
71
72struct MemPtr {};
73using MemPtrT = void (MemPtr::*)();
74using MemDataT = int(MemPtr::*);
75
76// CHECK-LABEL: @_Z12mem_ptr_testM6MemPtrFvvES1_
77auto mem_ptr_test(MemPtrT x, MemPtrT y) {
Eric Fiselier2ab957e2018-05-07 23:15:34 +000078 // CHECK: %[[DEST:retval|agg.result]]
79 // CHECK: %cmp.ptr = icmp eq [[TY:i[0-9]+]] %lhs.memptr.ptr, %rhs.memptr.ptr
80 // CHECK: %cmp.ptr.null = icmp eq [[TY]] %lhs.memptr.ptr, 0
81 // CHECK: %cmp.adj = icmp eq [[TY]] %lhs.memptr.adj, %rhs.memptr.adj
Eric Fiselier98a1cab2018-05-08 07:56:05 +000082 // CHECK: %[[OR:.*]] = or i1
83 // CHECK-SAME %cmp.adj
Eric Fiselier2ab957e2018-05-07 23:15:34 +000084 // CHECK: %memptr.eq = and i1 %cmp.ptr, %[[OR]]
Eric Fiselier0683c0e2018-05-07 21:07:10 +000085 // CHECK: %sel.eq = select i1 %memptr.eq, i8 [[EQ]], i8 [[NE]]
Eric Fiselier2ab957e2018-05-07 23:15:34 +000086 // CHECK: %__value_ = getelementptr inbounds %[[SE]], %[[SE]]* %[[DEST]]
87 // CHECK: store i8 %sel.eq, i8* %__value_, align 1
Eric Fiselier0683c0e2018-05-07 21:07:10 +000088 // CHECK: ret
89 return x <=> y;
90}
91
92// CHECK-LABEL: @_Z13mem_data_testM6MemPtriS0_
93auto mem_data_test(MemDataT x, MemDataT y) {
Eric Fiselier2ab957e2018-05-07 23:15:34 +000094 // CHECK: %[[DEST:retval|agg.result]]
95 // CHECK: %[[CMP:.*]] = icmp eq i{{[0-9]+}} %0, %1
Eric Fiselier0683c0e2018-05-07 21:07:10 +000096 // CHECK: %sel.eq = select i1 %[[CMP]], i8 [[EQ]], i8 [[NE]]
Eric Fiselier2ab957e2018-05-07 23:15:34 +000097 // CHECK: %__value_ = getelementptr inbounds %[[SE]], %[[SE]]* %[[DEST]]
98 // CHECK: store i8 %sel.eq, i8* %__value_, align 1
Eric Fiselier0683c0e2018-05-07 21:07:10 +000099 return x <=> y;
100}
101
102// CHECK-LABEL: @_Z13test_constantv
103auto test_constant() {
Eric Fiselier2ab957e2018-05-07 23:15:34 +0000104 // CHECK: %[[DEST:retval|agg.result]]
Eric Fiselier0683c0e2018-05-07 21:07:10 +0000105 // CHECK-NOT: icmp
Eric Fiselier2ab957e2018-05-07 23:15:34 +0000106 // CHECK: %__value_ = getelementptr inbounds %[[SO]], %[[SO]]* %[[DEST]]
107 // CHECK-NEXT: store i8 -1, i8* %__value_
108 // CHECK: ret
Eric Fiselier0683c0e2018-05-07 21:07:10 +0000109 const int x = 42;
110 const int y = 101;
111 return x <=> y;
112}
113
114// CHECK-LABEL: @_Z16test_nullptr_objPiDn
115auto test_nullptr_obj(int* x, decltype(nullptr) y) {
Eric Fiselier2ab957e2018-05-07 23:15:34 +0000116 // CHECK: %[[DEST:retval|agg.result]]
Eric Fiselier0683c0e2018-05-07 21:07:10 +0000117 // CHECK: %cmp.eq = icmp eq i32* %0, null
118 // CHECK: %sel.eq = select i1 %cmp.eq, i8 [[EQ]], i8 [[NE]]
Eric Fiselier2ab957e2018-05-07 23:15:34 +0000119 // CHECK: %__value_ = getelementptr inbounds %[[SE]], %[[SE]]* %[[DEST]]
120 // CHECK: store i8 %sel.eq, i8* %__value_, align 1
Eric Fiselier0683c0e2018-05-07 21:07:10 +0000121 return x <=> y;
122}
123
Eric Fiselier2ab957e2018-05-07 23:15:34 +0000124// CHECK-LABEL: @_Z18unscoped_enum_testijxy
125void unscoped_enum_test(int i, unsigned u, long long l, unsigned long long ul) {
Eric Fiselier0683c0e2018-05-07 21:07:10 +0000126 enum EnumA : int { A };
127 enum EnumB : unsigned { B };
128 // CHECK: %[[I:.*]] = load {{.*}} %i.addr
129 // CHECK: icmp slt i32 {{.*}} %[[I]]
130 (void)(A <=> i);
131
132 // CHECK: %[[U:.*]] = load {{.*}} %u.addr
133 // CHECK: icmp ult i32 {{.*}} %[[U]]
134 (void)(A <=> u);
135
136 // CHECK: %[[L:.*]] = load {{.*}} %l.addr
137 // CHECK: icmp slt i64 {{.*}} %[[L]]
138 (void)(A <=> l);
139
140 // CHECK: %[[U2:.*]] = load {{.*}} %u.addr
141 // CHECK: icmp ult i32 {{.*}} %[[U2]]
142 (void)(B <=> u);
143
144 // CHECK: %[[UL:.*]] = load {{.*}} %ul.addr
145 // CHECK: icmp ult i64 {{.*}} %[[UL]]
146 (void)(B <=> ul);
147}
148
149namespace NullptrTest {
150using nullptr_t = decltype(nullptr);
151
152// CHECK-LABEL: @_ZN11NullptrTest4testEDnDn(
153auto test(nullptr_t x, nullptr_t y) {
Eric Fiselier2ab957e2018-05-07 23:15:34 +0000154 // CHECK: %[[DEST:retval|agg.result]]
Eric Fiselier0683c0e2018-05-07 21:07:10 +0000155 // CHECK-NOT: select
Eric Fiselier2ab957e2018-05-07 23:15:34 +0000156 // CHECK: %__value_ = getelementptr inbounds %[[SE]], %[[SE]]* %[[DEST]]
Eric Fiselier0683c0e2018-05-07 21:07:10 +0000157 // CHECK-NEXT: store i8 [[EQ]], i8* %__value_
158 // CHECK: ret
159 return x <=> y;
160}
161} // namespace NullptrTest
162
163namespace ComplexTest {
164
165auto test_float(_Complex float x, _Complex float y) {
Eric Fiselier2ab957e2018-05-07 23:15:34 +0000166 // CHECK: %[[DEST:retval|agg.result]]
Eric Fiselier0683c0e2018-05-07 21:07:10 +0000167 // CHECK: %cmp.eq.r = fcmp oeq float %x.real, %y.real
168 // CHECK: %cmp.eq.i = fcmp oeq float %x.imag, %y.imag
169 // CHECK: %and.eq = and i1 %cmp.eq.r, %cmp.eq.i
170 // CHECK: %sel.eq = select i1 %and.eq, i8 [[EQ]], i8 [[NE]]
Eric Fiselier2ab957e2018-05-07 23:15:34 +0000171 // CHECK: %__value_ = getelementptr inbounds %[[WE]], %[[WE]]* %[[DEST]]
Eric Fiselier0683c0e2018-05-07 21:07:10 +0000172 // CHECK: store i8 %sel.eq, i8* %__value_, align 1
173 return x <=> y;
174}
175
176// CHECK-LABEL: @_ZN11ComplexTest8test_intECiS0_(
177auto test_int(_Complex int x, _Complex int y) {
Eric Fiselier2ab957e2018-05-07 23:15:34 +0000178 // CHECK: %[[DEST:retval|agg.result]]
Eric Fiselier0683c0e2018-05-07 21:07:10 +0000179 // CHECK: %cmp.eq.r = icmp eq i32 %x.real, %y.real
180 // CHECK: %cmp.eq.i = icmp eq i32 %x.imag, %y.imag
181 // CHECK: %and.eq = and i1 %cmp.eq.r, %cmp.eq.i
182 // CHECK: %sel.eq = select i1 %and.eq, i8 [[EQ]], i8 [[NE]]
Eric Fiselier2ab957e2018-05-07 23:15:34 +0000183 // CHECK: %__value_ = getelementptr inbounds %[[SE]], %[[SE]]* %[[DEST]]
Eric Fiselier0683c0e2018-05-07 21:07:10 +0000184 // CHECK: store i8 %sel.eq, i8* %__value_, align 1
185 return x <=> y;
186}
187
188} // namespace ComplexTest