1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt < %s -passes=instsimplify -S | FileCheck %s
4 ; Cycle through commuted variants where one operand of fcmp ord/uno is
5 ; known not-a-NAN and the other is repeated in the logically-connected fcmp.
7 declare float @llvm.fabs.f32(float)
8 declare void @llvm.assume(i1 noundef)
10 define i1 @ord1(float %x, float %y) {
12 ; CHECK-NEXT: [[CMP2:%.*]] = fcmp ord float [[X:%.*]], [[Y:%.*]]
13 ; CHECK-NEXT: ret i1 [[CMP2]]
15 %cmp1 = fcmp ord float 0.0, %x
16 %cmp2 = fcmp ord float %x, %y
17 %r = and i1 %cmp1, %cmp2
21 define i1 @ord1_assume(float %x, float %y, float %not.nan) {
22 ; CHECK-LABEL: @ord1_assume(
23 ; CHECK-NEXT: [[ORD:%.*]] = fcmp ord float [[NOT_NAN:%.*]], 0.000000e+00
24 ; CHECK-NEXT: call void @llvm.assume(i1 [[ORD]])
25 ; CHECK-NEXT: [[CMP2:%.*]] = fcmp ord float [[X:%.*]], [[Y:%.*]]
26 ; CHECK-NEXT: ret i1 [[CMP2]]
28 %ord = fcmp ord float %not.nan, 0.0
29 call void @llvm.assume(i1 %ord)
30 %cmp1 = fcmp ord float %not.nan, %x
31 %cmp2 = fcmp ord float %x, %y
32 %r = and i1 %cmp1, %cmp2
36 define i1 @ord2(double %x, double %y) {
38 ; CHECK-NEXT: [[CMP2:%.*]] = fcmp ord double [[Y:%.*]], [[X:%.*]]
39 ; CHECK-NEXT: ret i1 [[CMP2]]
41 %cmp1 = fcmp ord double 42.0, %x
42 %cmp2 = fcmp ord double %y, %x
43 %r = and i1 %cmp1, %cmp2
47 define <2 x i1> @ord3(<2 x float> %x, <2 x float> %y) {
49 ; CHECK-NEXT: [[CMP2:%.*]] = fcmp ord <2 x float> [[X:%.*]], [[Y:%.*]]
50 ; CHECK-NEXT: ret <2 x i1> [[CMP2]]
52 %cmp1 = fcmp ord <2 x float> %x, zeroinitializer
53 %cmp2 = fcmp ord <2 x float> %x, %y
54 %r = and <2 x i1> %cmp1, %cmp2
58 define i1 @ord3_assume(float %x, float %y, float %not.nan) {
59 ; CHECK-LABEL: @ord3_assume(
60 ; CHECK-NEXT: [[ORD:%.*]] = fcmp ord float [[NOT_NAN:%.*]], 0.000000e+00
61 ; CHECK-NEXT: call void @llvm.assume(i1 [[ORD]])
62 ; CHECK-NEXT: [[CMP2:%.*]] = fcmp ord float [[X:%.*]], [[Y:%.*]]
63 ; CHECK-NEXT: ret i1 [[CMP2]]
65 %ord = fcmp ord float %not.nan, 0.0
66 call void @llvm.assume(i1 %ord)
67 %cmp1 = fcmp ord float %x, %not.nan
68 %cmp2 = fcmp ord float %x, %y
69 %r = and i1 %cmp1, %cmp2
73 define <2 x i1> @ord4(<2 x double> %x, <2 x double> %y) {
75 ; CHECK-NEXT: [[CMP2:%.*]] = fcmp ord <2 x double> [[Y:%.*]], [[X:%.*]]
76 ; CHECK-NEXT: ret <2 x i1> [[CMP2]]
78 %cmp1 = fcmp ord <2 x double> %x, <double 42.0, double 42.0>
79 %cmp2 = fcmp ord <2 x double> %y, %x
80 %r = and <2 x i1> %cmp1, %cmp2
84 define i1 @ord5(float %x, float %y) {
86 ; CHECK-NEXT: [[CMP1:%.*]] = fcmp ord float [[X:%.*]], [[Y:%.*]]
87 ; CHECK-NEXT: ret i1 [[CMP1]]
89 %nnan = fdiv nnan float %x, %y
90 %cmp1 = fcmp ord float %x, %y
91 %cmp2 = fcmp ord float %nnan, %x
92 %r = and i1 %cmp1, %cmp2
96 define i1 @ord5_assume(float %x, float %y, float %nnan) {
97 ; CHECK-LABEL: @ord5_assume(
98 ; CHECK-NEXT: [[ORD:%.*]] = fcmp ord float [[NNAN:%.*]], 0.000000e+00
99 ; CHECK-NEXT: call void @llvm.assume(i1 [[ORD]])
100 ; CHECK-NEXT: [[CMP1:%.*]] = fcmp ord float [[X:%.*]], [[Y:%.*]]
101 ; CHECK-NEXT: ret i1 [[CMP1]]
103 %ord = fcmp ord float %nnan, 0.0
104 call void @llvm.assume(i1 %ord)
105 %cmp1 = fcmp ord float %x, %y
106 %cmp2 = fcmp ord float %nnan, %x
107 %r = and i1 %cmp1, %cmp2
111 define i1 @ord6(double %x, double %y) {
112 ; CHECK-LABEL: @ord6(
113 ; CHECK-NEXT: [[CMP1:%.*]] = fcmp ord double [[Y:%.*]], [[X:%.*]]
114 ; CHECK-NEXT: ret i1 [[CMP1]]
116 %cmp1 = fcmp ord double %y, %x
117 %cmp2 = fcmp ord double 42.0, %x
118 %r = and i1 %cmp1, %cmp2
122 define i1 @ord6_assume(double %x, double %y, double %not.nan) {
123 ; CHECK-LABEL: @ord6_assume(
124 ; CHECK-NEXT: [[ORD:%.*]] = fcmp ord double [[NOT_NAN:%.*]], 0.000000e+00
125 ; CHECK-NEXT: call void @llvm.assume(i1 [[ORD]])
126 ; CHECK-NEXT: [[CMP1:%.*]] = fcmp ord double [[Y:%.*]], [[X:%.*]]
127 ; CHECK-NEXT: ret i1 [[CMP1]]
129 %ord = fcmp ord double %not.nan, 0.0
130 call void @llvm.assume(i1 %ord)
131 %cmp1 = fcmp ord double %y, %x
132 %cmp2 = fcmp ord double %not.nan, %x
133 %r = and i1 %cmp1, %cmp2
137 define <2 x i1> @ord7(<2 x float> %x, <2 x float> %y) {
138 ; CHECK-LABEL: @ord7(
139 ; CHECK-NEXT: [[CMP1:%.*]] = fcmp ord <2 x float> [[X:%.*]], [[Y:%.*]]
140 ; CHECK-NEXT: ret <2 x i1> [[CMP1]]
142 %cmp1 = fcmp ord <2 x float> %x, %y
143 %cmp2 = fcmp ord <2 x float> %x, zeroinitializer
144 %r = and <2 x i1> %cmp1, %cmp2
148 define i1 @ord7_assume(float %x, float %y, float %not.nan) {
149 ; CHECK-LABEL: @ord7_assume(
150 ; CHECK-NEXT: [[ORD:%.*]] = fcmp ord float [[NOT_NAN:%.*]], 0.000000e+00
151 ; CHECK-NEXT: call void @llvm.assume(i1 [[ORD]])
152 ; CHECK-NEXT: [[CMP1:%.*]] = fcmp ord float [[X:%.*]], [[Y:%.*]]
153 ; CHECK-NEXT: ret i1 [[CMP1]]
155 %ord = fcmp ord float %not.nan, 0.0
156 call void @llvm.assume(i1 %ord)
157 %cmp1 = fcmp ord float %x, %y
158 %cmp2 = fcmp ord float %x, %not.nan
159 %r = and i1 %cmp1, %cmp2
163 define <2 x i1> @ord8(<2 x double> %x, <2 x double> %y) {
164 ; CHECK-LABEL: @ord8(
165 ; CHECK-NEXT: [[CMP1:%.*]] = fcmp ord <2 x double> [[Y:%.*]], [[X:%.*]]
166 ; CHECK-NEXT: ret <2 x i1> [[CMP1]]
168 %cmp1 = fcmp ord <2 x double> %y, %x
169 %cmp2 = fcmp ord <2 x double> %x, <double 0.0, double 42.0>
170 %r = and <2 x i1> %cmp1, %cmp2
174 define i1 @uno1(float %x, float %y) {
175 ; CHECK-LABEL: @uno1(
176 ; CHECK-NEXT: [[CMP2:%.*]] = fcmp uno float [[X:%.*]], [[Y:%.*]]
177 ; CHECK-NEXT: ret i1 [[CMP2]]
179 %cmp1 = fcmp uno float 0.0, %x
180 %cmp2 = fcmp uno float %x, %y
181 %r = or i1 %cmp1, %cmp2
185 define i1 @uno2(double %x, double %y) {
186 ; CHECK-LABEL: @uno2(
187 ; CHECK-NEXT: [[CMP2:%.*]] = fcmp uno double [[Y:%.*]], [[X:%.*]]
188 ; CHECK-NEXT: ret i1 [[CMP2]]
190 %cmp1 = fcmp uno double 42.0, %x
191 %cmp2 = fcmp uno double %y, %x
192 %r = or i1 %cmp1, %cmp2
196 define <2 x i1> @uno3(<2 x float> %x, <2 x float> %y) {
197 ; CHECK-LABEL: @uno3(
198 ; CHECK-NEXT: [[CMP2:%.*]] = fcmp uno <2 x float> [[X:%.*]], [[Y:%.*]]
199 ; CHECK-NEXT: ret <2 x i1> [[CMP2]]
201 %cmp1 = fcmp uno <2 x float> %x, zeroinitializer
202 %cmp2 = fcmp uno <2 x float> %x, %y
203 %r = or <2 x i1> %cmp1, %cmp2
207 define <2 x i1> @uno4(<2 x double> %x, <2 x double> %y) {
208 ; CHECK-LABEL: @uno4(
209 ; CHECK-NEXT: [[CMP2:%.*]] = fcmp uno <2 x double> [[Y:%.*]], [[X:%.*]]
210 ; CHECK-NEXT: ret <2 x i1> [[CMP2]]
212 %cmp1 = fcmp uno <2 x double> %x, <double 42.0, double 42.0>
213 %cmp2 = fcmp uno <2 x double> %y, %x
214 %r = or <2 x i1> %cmp1, %cmp2
218 define i1 @uno5(float %x, float %y) {
219 ; CHECK-LABEL: @uno5(
220 ; CHECK-NEXT: [[CMP1:%.*]] = fcmp uno float [[X:%.*]], [[Y:%.*]]
221 ; CHECK-NEXT: ret i1 [[CMP1]]
223 %cmp1 = fcmp uno float %x, %y
224 %cmp2 = fcmp uno float 0.0, %x
225 %r = or i1 %cmp1, %cmp2
229 define i1 @uno6(double %x, double %y) {
230 ; CHECK-LABEL: @uno6(
231 ; CHECK-NEXT: [[CMP1:%.*]] = fcmp uno double [[Y:%.*]], [[X:%.*]]
232 ; CHECK-NEXT: ret i1 [[CMP1]]
234 %cmp1 = fcmp uno double %y, %x
235 %cmp2 = fcmp uno double 42.0, %x
236 %r = or i1 %cmp1, %cmp2
240 define <2 x i1> @uno7(<2 x float> %x, <2 x float> %y) {
241 ; CHECK-LABEL: @uno7(
242 ; CHECK-NEXT: [[CMP1:%.*]] = fcmp uno <2 x float> [[X:%.*]], [[Y:%.*]]
243 ; CHECK-NEXT: ret <2 x i1> [[CMP1]]
245 %nnan = fdiv nnan <2 x float> %x, %y
246 %cmp1 = fcmp uno <2 x float> %x, %y
247 %cmp2 = fcmp uno <2 x float> %x, %nnan
248 %r = or <2 x i1> %cmp1, %cmp2
252 define <2 x i1> @uno8(<2 x double> %x, <2 x double> %y) {
253 ; CHECK-LABEL: @uno8(
254 ; CHECK-NEXT: [[CMP1:%.*]] = fcmp uno <2 x double> [[Y:%.*]], [[X:%.*]]
255 ; CHECK-NEXT: ret <2 x i1> [[CMP1]]
257 %cmp1 = fcmp uno <2 x double> %y, %x
258 %cmp2 = fcmp uno <2 x double> %x, <double 0x7ff0000000000000, double 42.0>
259 %r = or <2 x i1> %cmp1, %cmp2