1; RUN: opt < %s -instsimplify -S | FileCheck %s
2
3; Cycle through commuted variants where one operand of fcmp ord/uno is
4; known not-a-NAN and the other is repeated in the logically-connected fcmp.
5
6define i1 @ord1(float %x, float %y) {
7; CHECK-LABEL: @ord1(
8; CHECK-NEXT:    [[CMP2:%.*]] = fcmp ord float %x, %y
9; CHECK-NEXT:    ret i1 [[CMP2]]
10;
11  %cmp1 = fcmp ord float 0.0, %x
12  %cmp2 = fcmp ord float %x, %y
13  %r = and i1 %cmp1, %cmp2
14  ret i1 %r
15}
16
17define i1 @ord2(double %x, double %y) {
18; CHECK-LABEL: @ord2(
19; CHECK-NEXT:    [[CMP2:%.*]] = fcmp ord double %y, %x
20; CHECK-NEXT:    ret i1 [[CMP2]]
21;
22  %cmp1 = fcmp ord double 42.0, %x
23  %cmp2 = fcmp ord double %y, %x
24  %r = and i1 %cmp1, %cmp2
25  ret i1 %r
26}
27
28define <2 x i1> @ord3(<2 x float> %x, <2 x float> %y) {
29; CHECK-LABEL: @ord3(
30; CHECK-NEXT:    [[CMP2:%.*]] = fcmp ord <2 x float> %x, %y
31; CHECK-NEXT:    ret <2 x i1> [[CMP2]]
32;
33  %cmp1 = fcmp ord <2 x float> %x, zeroinitializer
34  %cmp2 = fcmp ord <2 x float> %x, %y
35  %r = and <2 x i1> %cmp1, %cmp2
36  ret <2 x i1> %r
37}
38
39define <2 x i1> @ord4(<2 x double> %x, <2 x double> %y) {
40; CHECK-LABEL: @ord4(
41; CHECK-NEXT:    [[CMP2:%.*]] = fcmp ord <2 x double> %y, %x
42; CHECK-NEXT:    ret <2 x i1> [[CMP2]]
43;
44  %cmp1 = fcmp ord <2 x double> %x, <double 42.0, double 42.0>
45  %cmp2 = fcmp ord <2 x double> %y, %x
46  %r = and <2 x i1> %cmp1, %cmp2
47  ret <2 x i1> %r
48}
49
50define i1 @ord5(float %x, float %y) {
51; CHECK-LABEL: @ord5(
52; CHECK-NEXT:    [[CMP1:%.*]] = fcmp ord float %x, %y
53; CHECK-NEXT:    ret i1 [[CMP1]]
54;
55  %nnan = fdiv nnan float %x, %y
56  %cmp1 = fcmp ord float %x, %y
57  %cmp2 = fcmp ord float %nnan, %x
58  %r = and i1 %cmp1, %cmp2
59  ret i1 %r
60}
61
62define i1 @ord6(double %x, double %y) {
63; CHECK-LABEL: @ord6(
64; CHECK-NEXT:    [[CMP1:%.*]] = fcmp ord double %y, %x
65; CHECK-NEXT:    ret i1 [[CMP1]]
66;
67  %cmp1 = fcmp ord double %y, %x
68  %cmp2 = fcmp ord double 42.0, %x
69  %r = and i1 %cmp1, %cmp2
70  ret i1 %r
71}
72
73define <2 x i1> @ord7(<2 x float> %x, <2 x float> %y) {
74; CHECK-LABEL: @ord7(
75; CHECK-NEXT:    [[CMP1:%.*]] = fcmp ord <2 x float> %x, %y
76; CHECK-NEXT:    ret <2 x i1> [[CMP1]]
77;
78  %cmp1 = fcmp ord <2 x float> %x, %y
79  %cmp2 = fcmp ord <2 x float> %x, zeroinitializer
80  %r = and <2 x i1> %cmp1, %cmp2
81  ret <2 x i1> %r
82}
83
84define <2 x i1> @ord8(<2 x double> %x, <2 x double> %y) {
85; CHECK-LABEL: @ord8(
86; CHECK-NEXT:    [[CMP1:%.*]] = fcmp ord <2 x double> %y, %x
87; CHECK-NEXT:    ret <2 x i1> [[CMP1]]
88;
89  %cmp1 = fcmp ord <2 x double> %y, %x
90  %cmp2 = fcmp ord <2 x double> %x, <double 0.0, double 42.0>
91  %r = and <2 x i1> %cmp1, %cmp2
92  ret <2 x i1> %r
93}
94
95define i1 @uno1(float %x, float %y) {
96; CHECK-LABEL: @uno1(
97; CHECK-NEXT:    [[CMP2:%.*]] = fcmp uno float %x, %y
98; CHECK-NEXT:    ret i1 [[CMP2]]
99;
100  %cmp1 = fcmp uno float 0.0, %x
101  %cmp2 = fcmp uno float %x, %y
102  %r = or i1 %cmp1, %cmp2
103  ret i1 %r
104}
105
106define i1 @uno2(double %x, double %y) {
107; CHECK-LABEL: @uno2(
108; CHECK-NEXT:    [[CMP2:%.*]] = fcmp uno double %y, %x
109; CHECK-NEXT:    ret i1 [[CMP2]]
110;
111  %cmp1 = fcmp uno double 42.0, %x
112  %cmp2 = fcmp uno double %y, %x
113  %r = or i1 %cmp1, %cmp2
114  ret i1 %r
115}
116
117define <2 x i1> @uno3(<2 x float> %x, <2 x float> %y) {
118; CHECK-LABEL: @uno3(
119; CHECK-NEXT:    [[CMP2:%.*]] = fcmp uno <2 x float> %x, %y
120; CHECK-NEXT:    ret <2 x i1> [[CMP2]]
121;
122  %cmp1 = fcmp uno <2 x float> %x, zeroinitializer
123  %cmp2 = fcmp uno <2 x float> %x, %y
124  %r = or <2 x i1> %cmp1, %cmp2
125  ret <2 x i1> %r
126}
127
128define <2 x i1> @uno4(<2 x double> %x, <2 x double> %y) {
129; CHECK-LABEL: @uno4(
130; CHECK-NEXT:    [[CMP2:%.*]] = fcmp uno <2 x double> %y, %x
131; CHECK-NEXT:    ret <2 x i1> [[CMP2]]
132;
133  %cmp1 = fcmp uno <2 x double> %x, <double 42.0, double 42.0>
134  %cmp2 = fcmp uno <2 x double> %y, %x
135  %r = or <2 x i1> %cmp1, %cmp2
136  ret <2 x i1> %r
137}
138
139define i1 @uno5(float %x, float %y) {
140; CHECK-LABEL: @uno5(
141; CHECK-NEXT:    [[CMP1:%.*]] = fcmp uno float %x, %y
142; CHECK-NEXT:    ret i1 [[CMP1]]
143;
144  %cmp1 = fcmp uno float %x, %y
145  %cmp2 = fcmp uno float 0.0, %x
146  %r = or i1 %cmp1, %cmp2
147  ret i1 %r
148}
149
150define i1 @uno6(double %x, double %y) {
151; CHECK-LABEL: @uno6(
152; CHECK-NEXT:    [[CMP1:%.*]] = fcmp uno double %y, %x
153; CHECK-NEXT:    ret i1 [[CMP1]]
154;
155  %cmp1 = fcmp uno double %y, %x
156  %cmp2 = fcmp uno double 42.0, %x
157  %r = or i1 %cmp1, %cmp2
158  ret i1 %r
159}
160
161define <2 x i1> @uno7(<2 x float> %x, <2 x float> %y) {
162; CHECK-LABEL: @uno7(
163; CHECK-NEXT:    [[CMP1:%.*]] = fcmp uno <2 x float> %x, %y
164; CHECK-NEXT:    ret <2 x i1> [[CMP1]]
165;
166  %nnan = fdiv nnan <2 x float> %x, %y
167  %cmp1 = fcmp uno <2 x float> %x, %y
168  %cmp2 = fcmp uno <2 x float> %x, %nnan
169  %r = or <2 x i1> %cmp1, %cmp2
170  ret <2 x i1> %r
171}
172
173define <2 x i1> @uno8(<2 x double> %x, <2 x double> %y) {
174; CHECK-LABEL: @uno8(
175; CHECK-NEXT:    [[CMP1:%.*]] = fcmp uno <2 x double> %y, %x
176; CHECK-NEXT:    ret <2 x i1> [[CMP1]]
177;
178  %cmp1 = fcmp uno <2 x double> %y, %x
179  %cmp2 = fcmp uno <2 x double> %x, <double 0x7ff0000000000000, double 42.0>
180  %r = or <2 x i1> %cmp1, %cmp2
181  ret <2 x i1> %r
182}
183
184