1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt < %s -instcombine -S | FileCheck %s
3
4define i1 @eq_zero(i4 %x, i4 %y) {
5; CHECK-LABEL: @eq_zero(
6; CHECK-NEXT:    [[I0:%.*]] = icmp eq i4 [[X:%.*]], 0
7; CHECK-NEXT:    [[I1:%.*]] = icmp eq i4 [[Y:%.*]], 0
8; CHECK-NEXT:    [[R:%.*]] = xor i1 [[I0]], [[I1]]
9; CHECK-NEXT:    ret i1 [[R]]
10;
11  %i0 = icmp eq i4 %x, 0
12  %i1 = icmp eq i4 %y, 0
13  %r = xor i1 %i0, %i1
14  ret i1 %r
15}
16
17define i1 @ne_zero(i4 %x, i4 %y) {
18; CHECK-LABEL: @ne_zero(
19; CHECK-NEXT:    [[I0:%.*]] = icmp ne i4 [[X:%.*]], 0
20; CHECK-NEXT:    [[I1:%.*]] = icmp ne i4 [[Y:%.*]], 0
21; CHECK-NEXT:    [[R:%.*]] = xor i1 [[I0]], [[I1]]
22; CHECK-NEXT:    ret i1 [[R]]
23;
24  %i0 = icmp ne i4 %x, 0
25  %i1 = icmp ne i4 %y, 0
26  %r = xor i1 %i0, %i1
27  ret i1 %r
28}
29
30define i1 @eq_ne_zero(i4 %x, i4 %y) {
31; CHECK-LABEL: @eq_ne_zero(
32; CHECK-NEXT:    [[I0:%.*]] = icmp eq i4 [[X:%.*]], 0
33; CHECK-NEXT:    [[I1:%.*]] = icmp ne i4 [[Y:%.*]], 0
34; CHECK-NEXT:    [[R:%.*]] = xor i1 [[I0]], [[I1]]
35; CHECK-NEXT:    ret i1 [[R]]
36;
37  %i0 = icmp eq i4 %x, 0
38  %i1 = icmp ne i4 %y, 0
39  %r = xor i1 %i0, %i1
40  ret i1 %r
41}
42
43define i1 @slt_zero(i4 %x, i4 %y) {
44; CHECK-LABEL: @slt_zero(
45; CHECK-NEXT:    [[TMP1:%.*]] = xor i4 [[X:%.*]], [[Y:%.*]]
46; CHECK-NEXT:    [[TMP2:%.*]] = icmp slt i4 [[TMP1]], 0
47; CHECK-NEXT:    ret i1 [[TMP2]]
48;
49  %i0 = icmp slt i4 %x, 0
50  %i1 = icmp slt i4 %y, 0
51  %r = xor i1 %i0, %i1
52  ret i1 %r
53}
54
55; Don't increase the instruction count.
56
57declare void @use(i1)
58
59define i1 @slt_zero_extra_uses(i4 %x, i4 %y) {
60; CHECK-LABEL: @slt_zero_extra_uses(
61; CHECK-NEXT:    [[I0:%.*]] = icmp slt i4 [[X:%.*]], 0
62; CHECK-NEXT:    [[I1:%.*]] = icmp slt i4 [[Y:%.*]], 0
63; CHECK-NEXT:    [[R:%.*]] = xor i1 [[I0]], [[I1]]
64; CHECK-NEXT:    call void @use(i1 [[I0]])
65; CHECK-NEXT:    call void @use(i1 [[I1]])
66; CHECK-NEXT:    ret i1 [[R]]
67;
68  %i0 = icmp slt i4 %x, 0
69  %i1 = icmp slt i4 %y, 0
70  %r = xor i1 %i0, %i1
71  call void @use(i1 %i0)
72  call void @use(i1 %i1)
73  ret i1 %r
74}
75
76define i1 @sgt_zero(i4 %x, i4 %y) {
77; CHECK-LABEL: @sgt_zero(
78; CHECK-NEXT:    [[I0:%.*]] = icmp sgt i4 [[X:%.*]], 0
79; CHECK-NEXT:    [[I1:%.*]] = icmp sgt i4 [[Y:%.*]], 0
80; CHECK-NEXT:    [[R:%.*]] = xor i1 [[I0]], [[I1]]
81; CHECK-NEXT:    ret i1 [[R]]
82;
83  %i0 = icmp sgt i4 %x, 0
84  %i1 = icmp sgt i4 %y, 0
85  %r = xor i1 %i0, %i1
86  ret i1 %r
87}
88
89define i1 @sgt_minus1(i4 %x, i4 %y) {
90; CHECK-LABEL: @sgt_minus1(
91; CHECK-NEXT:    [[TMP1:%.*]] = xor i4 [[X:%.*]], [[Y:%.*]]
92; CHECK-NEXT:    [[TMP2:%.*]] = icmp slt i4 [[TMP1]], 0
93; CHECK-NEXT:    ret i1 [[TMP2]]
94;
95  %i0 = icmp sgt i4 %x, -1
96  %i1 = icmp sgt i4 %y, -1
97  %r = xor i1 %i0, %i1
98  ret i1 %r
99}
100
101define i1 @slt_zero_sgt_minus1(i4 %x, i4 %y) {
102; CHECK-LABEL: @slt_zero_sgt_minus1(
103; CHECK-NEXT:    [[TMP1:%.*]] = xor i4 [[X:%.*]], [[Y:%.*]]
104; CHECK-NEXT:    [[TMP2:%.*]] = icmp sgt i4 [[TMP1]], -1
105; CHECK-NEXT:    ret i1 [[TMP2]]
106;
107  %i0 = icmp slt i4 %x, 0
108  %i1 = icmp sgt i4 %y, -1
109  %r = xor i1 %i0, %i1
110  ret i1 %r
111}
112
113define <2 x i1> @sgt_minus1_slt_zero_sgt(<2 x i4> %x, <2 x i4> %y) {
114; CHECK-LABEL: @sgt_minus1_slt_zero_sgt(
115; CHECK-NEXT:    [[TMP1:%.*]] = xor <2 x i4> [[Y:%.*]], [[X:%.*]]
116; CHECK-NEXT:    [[TMP2:%.*]] = icmp sgt <2 x i4> [[TMP1]], <i4 -1, i4 -1>
117; CHECK-NEXT:    ret <2 x i1> [[TMP2]]
118;
119  %i1 = icmp sgt <2 x i4> %x, <i4 -1, i4 -1>
120  %i0 = icmp slt <2 x i4> %y, zeroinitializer
121  %r = xor <2 x i1> %i0, %i1
122  ret <2 x i1> %r
123}
124
125; Don't try (crash) if the operand types don't match.
126
127define i1 @different_type_cmp_ops(i32 %x, i64 %y) {
128; CHECK-LABEL: @different_type_cmp_ops(
129; CHECK-NEXT:    [[CMP1:%.*]] = icmp slt i32 [[X:%.*]], 0
130; CHECK-NEXT:    [[CMP2:%.*]] = icmp slt i64 [[Y:%.*]], 0
131; CHECK-NEXT:    [[R:%.*]] = xor i1 [[CMP1]], [[CMP2]]
132; CHECK-NEXT:    ret i1 [[R]]
133;
134  %cmp1 = icmp slt i32 %x, 0
135  %cmp2 = icmp slt i64 %y, 0
136  %r = xor i1 %cmp1, %cmp2
137  ret i1 %r
138}
139
140define i1 @test13(i8 %A, i8 %B) {
141; CHECK-LABEL: @test13(
142; CHECK-NEXT:    [[TMP1:%.*]] = icmp ne i8 [[A:%.*]], [[B:%.*]]
143; CHECK-NEXT:    ret i1 [[TMP1]]
144;
145  %C = icmp ult i8 %A, %B
146  %D = icmp ugt i8 %A, %B
147  %E = xor i1 %C, %D
148  ret i1 %E
149}
150
151define i1 @test14(i8 %A, i8 %B) {
152; CHECK-LABEL: @test14(
153; CHECK-NEXT:    ret i1 true
154;
155  %C = icmp eq i8 %A, %B
156  %D = icmp ne i8 %B, %A
157  %E = xor i1 %C, %D
158  ret i1 %E
159}
160
161define i1 @xor_icmp_ptr(i8* %c, i8* %d) {
162; CHECK-LABEL: @xor_icmp_ptr(
163; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i8* [[C:%.*]], null
164; CHECK-NEXT:    [[CMP1:%.*]] = icmp slt i8* [[D:%.*]], null
165; CHECK-NEXT:    [[XOR:%.*]] = xor i1 [[CMP]], [[CMP1]]
166; CHECK-NEXT:    ret i1 [[XOR]]
167;
168  %cmp = icmp slt i8* %c, null
169  %cmp1 = icmp slt i8* %d, null
170  %xor = xor i1 %cmp, %cmp1
171  ret i1 %xor
172}
173
174