LLVM 24.0.0git
AMDGPUISelLowering.cpp
Go to the documentation of this file.
1//===-- AMDGPUISelLowering.cpp - AMDGPU Common DAG lowering functions -----===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9/// \file
10/// This is the parent TargetLowering class for hardware code gen
11/// targets.
12//
13//===----------------------------------------------------------------------===//
14
15#include "AMDGPUISelLowering.h"
16#include "AMDGPU.h"
17#include "AMDGPUInstrInfo.h"
19#include "AMDGPUMemoryUtils.h"
26#include "llvm/IR/IntrinsicsAMDGPU.h"
31
32using namespace llvm;
33
34#define GET_CALLING_CONV_IMPL
35#include "AMDGPUGenCallingConv.inc"
36
38 "amdgpu-bypass-slow-div",
39 cl::desc("Skip 64-bit divide for dynamic 32-bit values"),
40 cl::init(true));
41
42// Find a larger type to do a load / store of a vector with.
44 unsigned StoreSize = VT.getStoreSizeInBits();
45 if (StoreSize <= 32)
46 return EVT::getIntegerVT(Ctx, StoreSize);
47
48 if (StoreSize % 32 == 0)
49 return EVT::getVectorVT(Ctx, MVT::i32, StoreSize / 32);
50
51 return VT;
52}
53
57
59 // In order for this to be a signed 24-bit value, bit 23, must
60 // be a sign bit.
61 return DAG.ComputeMaxSignificantBits(Op);
62}
63
65 const TargetSubtargetInfo &STI,
66 const AMDGPUSubtarget &AMDGPUSTI)
67 : TargetLowering(TM, STI), Subtarget(&AMDGPUSTI) {
68 // Always lower memset, memcpy, and memmove intrinsics to load/store
69 // instructions, rather then generating calls to memset, mempcy or memmove.
73
74 // Enable ganging up loads and stores in the memcpy DAG lowering.
76
77 // Lower floating point store/load to integer store/load to reduce the number
78 // of patterns in tablegen.
80 AddPromotedToType(ISD::LOAD, MVT::f32, MVT::i32);
81
83 AddPromotedToType(ISD::LOAD, MVT::v2f32, MVT::v2i32);
84
86 AddPromotedToType(ISD::LOAD, MVT::v3f32, MVT::v3i32);
87
89 AddPromotedToType(ISD::LOAD, MVT::v4f32, MVT::v4i32);
90
92 AddPromotedToType(ISD::LOAD, MVT::v5f32, MVT::v5i32);
93
95 AddPromotedToType(ISD::LOAD, MVT::v6f32, MVT::v6i32);
96
98 AddPromotedToType(ISD::LOAD, MVT::v7f32, MVT::v7i32);
99
101 AddPromotedToType(ISD::LOAD, MVT::v8f32, MVT::v8i32);
102
104 AddPromotedToType(ISD::LOAD, MVT::v9f32, MVT::v9i32);
105
106 setOperationAction(ISD::LOAD, MVT::v10f32, Promote);
107 AddPromotedToType(ISD::LOAD, MVT::v10f32, MVT::v10i32);
108
109 setOperationAction(ISD::LOAD, MVT::v11f32, Promote);
110 AddPromotedToType(ISD::LOAD, MVT::v11f32, MVT::v11i32);
111
112 setOperationAction(ISD::LOAD, MVT::v12f32, Promote);
113 AddPromotedToType(ISD::LOAD, MVT::v12f32, MVT::v12i32);
114
115 setOperationAction(ISD::LOAD, MVT::v16f32, Promote);
116 AddPromotedToType(ISD::LOAD, MVT::v16f32, MVT::v16i32);
117
118 setOperationAction(ISD::LOAD, MVT::v32f32, Promote);
119 AddPromotedToType(ISD::LOAD, MVT::v32f32, MVT::v32i32);
120
122 AddPromotedToType(ISD::LOAD, MVT::i64, MVT::v2i32);
123
125 AddPromotedToType(ISD::LOAD, MVT::v2i64, MVT::v4i32);
126
128 AddPromotedToType(ISD::LOAD, MVT::f64, MVT::v2i32);
129
131 AddPromotedToType(ISD::LOAD, MVT::v2f64, MVT::v4i32);
132
134 AddPromotedToType(ISD::LOAD, MVT::v3i64, MVT::v6i32);
135
137 AddPromotedToType(ISD::LOAD, MVT::v4i64, MVT::v8i32);
138
140 AddPromotedToType(ISD::LOAD, MVT::v3f64, MVT::v6i32);
141
143 AddPromotedToType(ISD::LOAD, MVT::v4f64, MVT::v8i32);
144
146 AddPromotedToType(ISD::LOAD, MVT::v8i64, MVT::v16i32);
147
149 AddPromotedToType(ISD::LOAD, MVT::v8f64, MVT::v16i32);
150
151 setOperationAction(ISD::LOAD, MVT::v16i64, Promote);
152 AddPromotedToType(ISD::LOAD, MVT::v16i64, MVT::v32i32);
153
154 setOperationAction(ISD::LOAD, MVT::v16f64, Promote);
155 AddPromotedToType(ISD::LOAD, MVT::v16f64, MVT::v32i32);
156
158 AddPromotedToType(ISD::LOAD, MVT::i128, MVT::v4i32);
159
160 // There are no 64-bit extloads. These should be done as a 32-bit extload and
161 // an extension to 64-bit.
162 for (MVT VT : MVT::integer_valuetypes())
164 Expand);
165
166 for (MVT VT : MVT::integer_valuetypes()) {
167 if (VT == MVT::i64)
168 continue;
169
170 for (auto Op : {ISD::SEXTLOAD, ISD::ZEXTLOAD, ISD::EXTLOAD}) {
171 setLoadExtAction(Op, VT, MVT::i1, Promote);
172 setLoadExtAction(Op, VT, MVT::i8, Legal);
173 setLoadExtAction(Op, VT, MVT::i16, Legal);
174 setLoadExtAction(Op, VT, MVT::i32, Expand);
175 }
176 }
177
179 for (auto MemVT :
180 {MVT::v2i8, MVT::v4i8, MVT::v2i16, MVT::v3i16, MVT::v4i16})
182 Expand);
183
184 setLoadExtAction(ISD::EXTLOAD, MVT::f32, MVT::f16, Expand);
185 setLoadExtAction(ISD::EXTLOAD, MVT::f32, MVT::bf16, Expand);
186 setLoadExtAction(ISD::EXTLOAD, MVT::v2f32, MVT::v2f16, Expand);
187 setLoadExtAction(ISD::EXTLOAD, MVT::v2f32, MVT::v2bf16, Expand);
188 setLoadExtAction(ISD::EXTLOAD, MVT::v3f32, MVT::v3f16, Expand);
189 setLoadExtAction(ISD::EXTLOAD, MVT::v3f32, MVT::v3bf16, Expand);
190 setLoadExtAction(ISD::EXTLOAD, MVT::v4f32, MVT::v4f16, Expand);
191 setLoadExtAction(ISD::EXTLOAD, MVT::v4f32, MVT::v4bf16, Expand);
192 setLoadExtAction(ISD::EXTLOAD, MVT::v8f32, MVT::v8f16, Expand);
193 setLoadExtAction(ISD::EXTLOAD, MVT::v8f32, MVT::v8bf16, Expand);
194 setLoadExtAction(ISD::EXTLOAD, MVT::v16f32, MVT::v16f16, Expand);
195 setLoadExtAction(ISD::EXTLOAD, MVT::v16f32, MVT::v16bf16, Expand);
196 setLoadExtAction(ISD::EXTLOAD, MVT::v32f32, MVT::v32f16, Expand);
197 setLoadExtAction(ISD::EXTLOAD, MVT::v32f32, MVT::v32bf16, Expand);
198
199 setLoadExtAction(ISD::EXTLOAD, MVT::f64, MVT::f32, Expand);
200 setLoadExtAction(ISD::EXTLOAD, MVT::v2f64, MVT::v2f32, Expand);
201 setLoadExtAction(ISD::EXTLOAD, MVT::v3f64, MVT::v3f32, Expand);
202 setLoadExtAction(ISD::EXTLOAD, MVT::v4f64, MVT::v4f32, Expand);
203 setLoadExtAction(ISD::EXTLOAD, MVT::v8f64, MVT::v8f32, Expand);
204 setLoadExtAction(ISD::EXTLOAD, MVT::v16f64, MVT::v16f32, Expand);
205
206 setLoadExtAction(ISD::EXTLOAD, MVT::f64, MVT::f16, Expand);
207 setLoadExtAction(ISD::EXTLOAD, MVT::f64, MVT::bf16, Expand);
208 setLoadExtAction(ISD::EXTLOAD, MVT::v2f64, MVT::v2f16, Expand);
209 setLoadExtAction(ISD::EXTLOAD, MVT::v2f64, MVT::v2bf16, Expand);
210 setLoadExtAction(ISD::EXTLOAD, MVT::v3f64, MVT::v3f16, Expand);
211 setLoadExtAction(ISD::EXTLOAD, MVT::v3f64, MVT::v3bf16, Expand);
212 setLoadExtAction(ISD::EXTLOAD, MVT::v4f64, MVT::v4f16, Expand);
213 setLoadExtAction(ISD::EXTLOAD, MVT::v4f64, MVT::v4bf16, Expand);
214 setLoadExtAction(ISD::EXTLOAD, MVT::v8f64, MVT::v8f16, Expand);
215 setLoadExtAction(ISD::EXTLOAD, MVT::v8f64, MVT::v8bf16, Expand);
216 setLoadExtAction(ISD::EXTLOAD, MVT::v16f64, MVT::v16f16, Expand);
217 setLoadExtAction(ISD::EXTLOAD, MVT::v16f64, MVT::v16bf16, Expand);
218
220 AddPromotedToType(ISD::STORE, MVT::f32, MVT::i32);
221
223 AddPromotedToType(ISD::STORE, MVT::v2f32, MVT::v2i32);
224
226 AddPromotedToType(ISD::STORE, MVT::v3f32, MVT::v3i32);
227
229 AddPromotedToType(ISD::STORE, MVT::v4f32, MVT::v4i32);
230
232 AddPromotedToType(ISD::STORE, MVT::v5f32, MVT::v5i32);
233
235 AddPromotedToType(ISD::STORE, MVT::v6f32, MVT::v6i32);
236
238 AddPromotedToType(ISD::STORE, MVT::v7f32, MVT::v7i32);
239
241 AddPromotedToType(ISD::STORE, MVT::v8f32, MVT::v8i32);
242
244 AddPromotedToType(ISD::STORE, MVT::v9f32, MVT::v9i32);
245
247 AddPromotedToType(ISD::STORE, MVT::v10f32, MVT::v10i32);
248
250 AddPromotedToType(ISD::STORE, MVT::v11f32, MVT::v11i32);
251
253 AddPromotedToType(ISD::STORE, MVT::v12f32, MVT::v12i32);
254
256 AddPromotedToType(ISD::STORE, MVT::v16f32, MVT::v16i32);
257
259 AddPromotedToType(ISD::STORE, MVT::v32f32, MVT::v32i32);
260
262 AddPromotedToType(ISD::STORE, MVT::i64, MVT::v2i32);
263
265 AddPromotedToType(ISD::STORE, MVT::v2i64, MVT::v4i32);
266
268 AddPromotedToType(ISD::STORE, MVT::f64, MVT::v2i32);
269
271 AddPromotedToType(ISD::STORE, MVT::v2f64, MVT::v4i32);
272
274 AddPromotedToType(ISD::STORE, MVT::v3i64, MVT::v6i32);
275
277 AddPromotedToType(ISD::STORE, MVT::v3f64, MVT::v6i32);
278
280 AddPromotedToType(ISD::STORE, MVT::v4i64, MVT::v8i32);
281
283 AddPromotedToType(ISD::STORE, MVT::v4f64, MVT::v8i32);
284
286 AddPromotedToType(ISD::STORE, MVT::v8i64, MVT::v16i32);
287
289 AddPromotedToType(ISD::STORE, MVT::v8f64, MVT::v16i32);
290
292 AddPromotedToType(ISD::STORE, MVT::v16i64, MVT::v32i32);
293
295 AddPromotedToType(ISD::STORE, MVT::v16f64, MVT::v32i32);
296
298 AddPromotedToType(ISD::STORE, MVT::i128, MVT::v4i32);
299
300 setTruncStoreAction(MVT::i64, MVT::i1, Expand);
301 setTruncStoreAction(MVT::i64, MVT::i8, Expand);
302 setTruncStoreAction(MVT::i64, MVT::i16, Expand);
303 setTruncStoreAction(MVT::i64, MVT::i32, Expand);
304
305 setTruncStoreAction(MVT::v2i64, MVT::v2i1, Expand);
306 setTruncStoreAction(MVT::v2i64, MVT::v2i8, Expand);
307 setTruncStoreAction(MVT::v2i64, MVT::v2i16, Expand);
308 setTruncStoreAction(MVT::v2i64, MVT::v2i32, Expand);
309
310 setTruncStoreAction(MVT::f32, MVT::bf16, Expand);
311 setTruncStoreAction(MVT::f32, MVT::f16, Expand);
312 setTruncStoreAction(MVT::v2f32, MVT::v2bf16, Expand);
313 setTruncStoreAction(MVT::v2f32, MVT::v2f16, Expand);
314 setTruncStoreAction(MVT::v3f32, MVT::v3bf16, Expand);
315 setTruncStoreAction(MVT::v3f32, MVT::v3f16, Expand);
316 setTruncStoreAction(MVT::v4f32, MVT::v4bf16, Expand);
317 setTruncStoreAction(MVT::v4f32, MVT::v4f16, Expand);
318 setTruncStoreAction(MVT::v6f32, MVT::v6f16, Expand);
319 setTruncStoreAction(MVT::v8f32, MVT::v8bf16, Expand);
320 setTruncStoreAction(MVT::v8f32, MVT::v8f16, Expand);
321 setTruncStoreAction(MVT::v16f32, MVT::v16bf16, Expand);
322 setTruncStoreAction(MVT::v16f32, MVT::v16f16, Expand);
323 setTruncStoreAction(MVT::v32f32, MVT::v32bf16, Expand);
324 setTruncStoreAction(MVT::v32f32, MVT::v32f16, Expand);
325
326 setTruncStoreAction(MVT::f64, MVT::bf16, Expand);
327 setTruncStoreAction(MVT::f64, MVT::f16, Expand);
328 setTruncStoreAction(MVT::f64, MVT::f32, Expand);
329
330 setTruncStoreAction(MVT::v2f64, MVT::v2f32, Expand);
331 setTruncStoreAction(MVT::v2f64, MVT::v2bf16, Expand);
332 setTruncStoreAction(MVT::v2f64, MVT::v2f16, Expand);
333
334 setTruncStoreAction(MVT::v3i32, MVT::v3i8, Expand);
335
336 setTruncStoreAction(MVT::v3i64, MVT::v3i32, Expand);
337 setTruncStoreAction(MVT::v3i64, MVT::v3i16, Expand);
338 setTruncStoreAction(MVT::v3i64, MVT::v3i8, Expand);
339 setTruncStoreAction(MVT::v3i64, MVT::v3i1, Expand);
340 setTruncStoreAction(MVT::v3f64, MVT::v3f32, Expand);
341 setTruncStoreAction(MVT::v3f64, MVT::v3bf16, Expand);
342 setTruncStoreAction(MVT::v3f64, MVT::v3f16, Expand);
343
344 setTruncStoreAction(MVT::v4i64, MVT::v4i32, Expand);
345 setTruncStoreAction(MVT::v4i64, MVT::v4i16, Expand);
346 setTruncStoreAction(MVT::v4f64, MVT::v4f32, Expand);
347 setTruncStoreAction(MVT::v4f64, MVT::v4bf16, Expand);
348 setTruncStoreAction(MVT::v4f64, MVT::v4f16, Expand);
349
350 setTruncStoreAction(MVT::v5i32, MVT::v5i1, Expand);
351 setTruncStoreAction(MVT::v5i32, MVT::v5i8, Expand);
352 setTruncStoreAction(MVT::v5i32, MVT::v5i16, Expand);
353
354 setTruncStoreAction(MVT::v6i32, MVT::v6i1, Expand);
355 setTruncStoreAction(MVT::v6i32, MVT::v6i8, Expand);
356 setTruncStoreAction(MVT::v6i32, MVT::v6i16, Expand);
357
358 setTruncStoreAction(MVT::v7i32, MVT::v7i1, Expand);
359 setTruncStoreAction(MVT::v7i32, MVT::v7i8, Expand);
360 setTruncStoreAction(MVT::v7i32, MVT::v7i16, Expand);
361
362 setTruncStoreAction(MVT::v8f64, MVT::v8f32, Expand);
363 setTruncStoreAction(MVT::v8f64, MVT::v8bf16, Expand);
364 setTruncStoreAction(MVT::v8f64, MVT::v8f16, Expand);
365
366 setTruncStoreAction(MVT::v16f64, MVT::v16f32, Expand);
367 setTruncStoreAction(MVT::v16f64, MVT::v16bf16, Expand);
368 setTruncStoreAction(MVT::v16f64, MVT::v16f16, Expand);
369 setTruncStoreAction(MVT::v16i64, MVT::v16i16, Expand);
370 setTruncStoreAction(MVT::v16i64, MVT::v16i8, Expand);
371 setTruncStoreAction(MVT::v16i64, MVT::v16i8, Expand);
372 setTruncStoreAction(MVT::v16i64, MVT::v16i1, Expand);
373
374 setOperationAction(ISD::Constant, {MVT::i32, MVT::i64}, Legal);
375 setOperationAction(ISD::ConstantFP, {MVT::f32, MVT::f64}, Legal);
376
378
379 // For R600, this is totally unsupported, just custom lower to produce an
380 // error.
382
383 // Library functions. These default to Expand, but we have instructions
384 // for them.
387 {MVT::f16, MVT::f32}, Legal);
389
391 setOperationAction(ISD::FROUND, {MVT::f32, MVT::f64}, Custom);
393 {MVT::f16, MVT::f32, MVT::f64}, Expand);
394
397 MVT::f32, Custom);
399
400 setOperationAction(ISD::FNEARBYINT, {MVT::f16, MVT::f32, MVT::f64}, Custom);
401
402 setOperationAction(ISD::FRINT, {MVT::f16, MVT::f32, MVT::f64}, Custom);
403
404 setOperationAction({ISD::LRINT, ISD::LLRINT}, {MVT::f16, MVT::f32, MVT::f64},
405 Expand);
406
407 setOperationAction(ISD::FREM, {MVT::f16, MVT::f32, MVT::f64}, Expand);
408 setOperationAction(ISD::IS_FPCLASS, {MVT::f32, MVT::f64}, Legal);
410
412 Custom);
413
414 setOperationAction(ISD::FCANONICALIZE, {MVT::f32, MVT::f64}, Legal);
415
416 // FIXME: These IS_FPCLASS vector fp types are marked custom so it reaches
417 // scalarization code. Can be removed when IS_FPCLASS expand isn't called by
418 // default unless marked custom/legal.
420 {MVT::v2f32, MVT::v3f32, MVT::v4f32, MVT::v5f32,
421 MVT::v6f32, MVT::v7f32, MVT::v8f32, MVT::v16f32,
422 MVT::v2f64, MVT::v3f64, MVT::v4f64, MVT::v8f64,
423 MVT::v16f64},
424 Custom);
425
426 // Expand to fneg + fadd.
428
430 {MVT::v3i32, MVT::v3f32, MVT::v4i32, MVT::v4f32,
431 MVT::v5i32, MVT::v5f32, MVT::v6i32, MVT::v6f32,
432 MVT::v7i32, MVT::v7f32, MVT::v8i32, MVT::v8f32,
433 MVT::v9i32, MVT::v9f32, MVT::v10i32, MVT::v10f32,
434 MVT::v11i32, MVT::v11f32, MVT::v12i32, MVT::v12f32},
435 Custom);
436
439 {MVT::v2f32, MVT::v2i32, MVT::v3f32, MVT::v3i32, MVT::v4f32,
440 MVT::v4i32, MVT::v5f32, MVT::v5i32, MVT::v6f32, MVT::v6i32,
441 MVT::v7f32, MVT::v7i32, MVT::v8f32, MVT::v8i32, MVT::v9f32,
442 MVT::v9i32, MVT::v10i32, MVT::v10f32, MVT::v11i32, MVT::v11f32,
443 MVT::v12i32, MVT::v12f32, MVT::v16i32, MVT::v32f32, MVT::v32i32,
444 MVT::v2f64, MVT::v2i64, MVT::v3f64, MVT::v3i64, MVT::v4f64,
445 MVT::v4i64, MVT::v8f64, MVT::v8i64, MVT::v16f64, MVT::v16i64},
446 Custom);
447
449 Expand);
450 setOperationAction(ISD::FP_TO_FP16, {MVT::f64, MVT::f32}, Custom);
451
452 const MVT ScalarIntVTs[] = { MVT::i32, MVT::i64 };
453 for (MVT VT : ScalarIntVTs) {
454 // These should use [SU]DIVREM, so set them to expand
456 Expand);
457
458 // GPU does not have divrem function for signed or unsigned.
460
461 // GPU does not have [S|U]MUL_LOHI functions as a single instruction.
463
465
467 Expand);
468 }
469
470 // The hardware supports 32-bit FSHR, but not FSHL.
472
473 setOperationAction({ISD::ROTL, ISD::ROTR}, {MVT::i32, MVT::i64}, Expand);
474
476
481 MVT::i64, Custom);
483
485 Legal);
486
489 MVT::i64, Custom);
490
491 for (auto VT : {MVT::i8, MVT::i16})
493
494 static const MVT::SimpleValueType VectorIntTypes[] = {
495 MVT::v2i32, MVT::v3i32, MVT::v4i32, MVT::v5i32, MVT::v6i32, MVT::v7i32,
496 MVT::v9i32, MVT::v10i32, MVT::v11i32, MVT::v12i32};
497
498 for (MVT VT : VectorIntTypes) {
499 // Expand the following operations for the current type by default.
500 // clang-format off
520 VT, Expand);
521 // clang-format on
522 }
523
524 static const MVT::SimpleValueType FloatVectorTypes[] = {
525 MVT::v2f32, MVT::v3f32, MVT::v4f32, MVT::v5f32, MVT::v6f32, MVT::v7f32,
526 MVT::v9f32, MVT::v10f32, MVT::v11f32, MVT::v12f32};
527
528 for (MVT VT : FloatVectorTypes) {
541 VT, Expand);
542 }
543
544 // This causes using an unrolled select operation rather than expansion with
545 // bit operations. This is in general better, but the alternative using BFI
546 // instructions may be better if the select sources are SGPRs.
548 AddPromotedToType(ISD::SELECT, MVT::v2f32, MVT::v2i32);
549
551 AddPromotedToType(ISD::SELECT, MVT::v3f32, MVT::v3i32);
552
554 AddPromotedToType(ISD::SELECT, MVT::v4f32, MVT::v4i32);
555
557 AddPromotedToType(ISD::SELECT, MVT::v5f32, MVT::v5i32);
558
560 AddPromotedToType(ISD::SELECT, MVT::v6f32, MVT::v6i32);
561
563 AddPromotedToType(ISD::SELECT, MVT::v7f32, MVT::v7i32);
564
566 AddPromotedToType(ISD::SELECT, MVT::v9f32, MVT::v9i32);
567
569 AddPromotedToType(ISD::SELECT, MVT::v10f32, MVT::v10i32);
570
572 AddPromotedToType(ISD::SELECT, MVT::v11f32, MVT::v11i32);
573
575 AddPromotedToType(ISD::SELECT, MVT::v12f32, MVT::v12i32);
576
578 setJumpIsExpensive(true);
579
582
584
585 // We want to find all load dependencies for long chains of stores to enable
586 // merging into very wide vectors. The problem is with vectors with > 4
587 // elements. MergeConsecutiveStores will attempt to merge these because x8/x16
588 // vectors are a legal type, even though we have to split the loads
589 // usually. When we can more precisely specify load legality per address
590 // space, we should be able to make FindBetterChain/MergeConsecutiveStores
591 // smarter so that they can figure out what to do in 2 iterations without all
592 // N > 4 stores on the same chain.
594
595 // memcpy/memmove/memset are expanded in the IR, so we shouldn't need to worry
596 // about these during lowering.
597 MaxStoresPerMemcpy = 0xffffffff;
598 MaxStoresPerMemmove = 0xffffffff;
599 MaxStoresPerMemset = 0xffffffff;
600
601 // The expansion for 64-bit division is enormous.
603 addBypassSlowDiv(64, 32);
604
615
619}
620
621//===----------------------------------------------------------------------===//
622// Target Information
623//===----------------------------------------------------------------------===//
624
626static bool fnegFoldsIntoOpcode(unsigned Opc) {
627 switch (Opc) {
628 case ISD::FADD:
629 case ISD::FSUB:
630 case ISD::FMUL:
631 case ISD::FMA:
632 case ISD::FMAD:
633 case ISD::FMINNUM:
634 case ISD::FMAXNUM:
637 case ISD::FMINIMUM:
638 case ISD::FMAXIMUM:
639 case ISD::FMINIMUMNUM:
640 case ISD::FMAXIMUMNUM:
641 case ISD::SELECT:
642 case ISD::FSIN:
643 case ISD::FTRUNC:
644 case ISD::FRINT:
645 case ISD::FNEARBYINT:
646 case ISD::FROUNDEVEN:
648 case AMDGPUISD::RCP:
649 case AMDGPUISD::RCP_LEGACY:
650 case AMDGPUISD::RCP_IFLAG:
651 case AMDGPUISD::SIN_HW:
652 case AMDGPUISD::FMUL_LEGACY:
653 case AMDGPUISD::FMIN_LEGACY:
654 case AMDGPUISD::FMAX_LEGACY:
655 case AMDGPUISD::FMED3:
656 // TODO: handle llvm.amdgcn.fma.legacy
657 return true;
658 case ISD::BITCAST:
659 llvm_unreachable("bitcast is special cased");
660 default:
661 return false;
662 }
663}
664
665static bool fnegFoldsIntoOp(const SDNode *N) {
666 unsigned Opc = N->getOpcode();
667 if (Opc == ISD::BITCAST) {
668 // TODO: Is there a benefit to checking the conditions performFNegCombine
669 // does? We don't for the other cases.
670 SDValue BCSrc = N->getOperand(0);
671 if (BCSrc.getOpcode() == ISD::BUILD_VECTOR) {
672 return BCSrc.getNumOperands() == 2 &&
673 BCSrc.getOperand(1).getValueSizeInBits() == 32;
674 }
675
676 return BCSrc.getOpcode() == ISD::SELECT && BCSrc.getValueType() == MVT::f32;
677 }
678
679 return fnegFoldsIntoOpcode(Opc);
680}
681
682/// \p returns true if the operation will definitely need to use a 64-bit
683/// encoding, and thus will use a VOP3 encoding regardless of the source
684/// modifiers.
686static bool opMustUseVOP3Encoding(const SDNode *N, MVT VT) {
687 return (N->getNumOperands() > 2 && N->getOpcode() != ISD::SELECT) ||
688 VT == MVT::f64;
689}
690
691/// Return true if v_cndmask_b32 will support fabs/fneg source modifiers for the
692/// type for ISD::SELECT.
694static bool selectSupportsSourceMods(const SDNode *N) {
695 // TODO: Only applies if select will be vector
696 return N->getValueType(0) == MVT::f32;
697}
698
699// Most FP instructions support source modifiers, but this could be refined
700// slightly.
702static bool hasSourceMods(const SDNode *N) {
703 if (isa<MemSDNode>(N))
704 return false;
705
706 switch (N->getOpcode()) {
707 case ISD::CopyToReg:
708 case ISD::FDIV:
709 case ISD::FREM:
710 case ISD::INLINEASM:
712 case AMDGPUISD::DIV_SCALE:
714
715 // TODO: Should really be looking at the users of the bitcast. These are
716 // problematic because bitcasts are used to legalize all stores to integer
717 // types.
718 case ISD::BITCAST:
719 return false;
721 switch (N->getConstantOperandVal(0)) {
722 case Intrinsic::amdgcn_interp_p1:
723 case Intrinsic::amdgcn_interp_p2:
724 case Intrinsic::amdgcn_interp_mov:
725 case Intrinsic::amdgcn_interp_p1_f16:
726 case Intrinsic::amdgcn_interp_p2_f16:
727 return false;
728 default:
729 return true;
730 }
731 }
732 case ISD::SELECT:
734 default:
735 return true;
736 }
737}
738
740 unsigned CostThreshold) {
741 // Some users (such as 3-operand FMA/MAD) must use a VOP3 encoding, and thus
742 // it is truly free to use a source modifier in all cases. If there are
743 // multiple users but for each one will necessitate using VOP3, there will be
744 // a code size increase. Try to avoid increasing code size unless we know it
745 // will save on the instruction count.
746 unsigned NumMayIncreaseSize = 0;
747 MVT VT = N->getValueType(0).getScalarType().getSimpleVT();
748
749 assert(!N->use_empty());
750
751 // XXX - Should this limit number of uses to check?
752 for (const SDNode *U : N->users()) {
753 if (!hasSourceMods(U))
754 return false;
755
756 if (!opMustUseVOP3Encoding(U, VT)) {
757 if (++NumMayIncreaseSize > CostThreshold)
758 return false;
759 }
760 }
761
762 return true;
763}
764
767 assert(!VT.isVector() && "only scalar expected");
768
769 // Round to the next multiple of 32-bits.
770 unsigned Size = VT.getSizeInBits();
771 if (Size <= 32)
772 return MVT::i32;
773 return EVT::getIntegerVT(Context, 32 * ((Size + 31) / 32));
774}
775
777 return 32;
778}
779
781 return true;
782}
783
784// The backend supports 32 and 64 bit floating point immediates.
785// FIXME: Why are we reporting vectors of FP immediates as legal?
788 bool ForCodeSize) const {
791}
792
793// We don't want to shrink f64 / f32 constants.
795 EVT ScalarVT = VT.getScalarType();
796 return (ScalarVT != MVT::f32 && ScalarVT != MVT::f64);
797}
798
800 SDNode *N, ISD::LoadExtType ExtTy, EVT NewVT,
801 std::optional<unsigned> ByteOffset) const {
802 // TODO: This may be worth removing. Check regression tests for diffs.
803 if (!TargetLoweringBase::shouldReduceLoadWidth(N, ExtTy, NewVT, ByteOffset))
804 return false;
805
806 unsigned NewSize = NewVT.getStoreSizeInBits();
807
808 // If we are reducing to a 32-bit load or a smaller multi-dword load,
809 // this is always better.
810 if (NewSize >= 32)
811 return true;
812
813 EVT OldVT = N->getValueType(0);
814 unsigned OldSize = OldVT.getStoreSizeInBits();
815
817 unsigned AS = MN->getAddressSpace();
818 // Do not shrink an aligned scalar load to sub-dword.
819 // Scalar engine cannot do sub-dword loads.
820 // Do not enable for gfx1250+ even though it has sub-dword loads because
821 // this will convert:
822 // i16 = trunc (zextload i16->i32)
823 // to:
824 // i16 = (load i16)
825 // This transformation will be reversed by LowerLOAD resulting in an infinite
826 // loop. Also, tablegen already has a pattern to match zextload i16->i32, but
827 // load i16 will not be matched since there is no instruction that does it.
828 if (OldSize >= 32 && NewSize < 32 && MN->getAlign() >= Align(4) &&
832 MN->isInvariant())) &&
834 return false;
835
836 // Don't produce extloads from sub 32-bit types. SI doesn't have scalar
837 // extloads, so doing one requires using a buffer_load. In cases where we
838 // still couldn't use a scalar load, using the wider load shouldn't really
839 // hurt anything.
840
841 // If the old size already had to be an extload, there's no harm in continuing
842 // to reduce the width.
843 return (OldSize < 32);
844}
845
847 const SelectionDAG &DAG,
848 const MachineMemOperand &MMO) const {
849
850 assert(LoadTy.getSizeInBits() == CastTy.getSizeInBits());
851
852 if (LoadTy.getScalarType() == MVT::i32)
853 return false;
854
855 unsigned LScalarSize = LoadTy.getScalarSizeInBits();
856 unsigned CastScalarSize = CastTy.getScalarSizeInBits();
857
858 if ((LScalarSize >= CastScalarSize) && (CastScalarSize < 32))
859 return false;
860
861 unsigned Fast = 0;
863 CastTy, MMO, &Fast) &&
864 Fast;
865}
866
867// SI+ has instructions for cttz / ctlz for 32-bit values. This is probably also
868// profitable with the expansion for 64-bit since it's generally good to
869// speculate things.
871 return true;
872}
873
875 return true;
876}
877
879 switch (N->getOpcode()) {
880 case ISD::EntryToken:
881 case ISD::TokenFactor:
882 return true;
884 unsigned IntrID = N->getConstantOperandVal(0);
886 }
888 unsigned IntrID = N->getConstantOperandVal(1);
890 }
891 case ISD::LOAD:
892 if (cast<LoadSDNode>(N)->getMemOperand()->getAddrSpace() ==
894 return true;
895 return false;
896 case AMDGPUISD::SETCC: // ballot-style instruction
897 return true;
898 }
899 return false;
900}
901
903 SDValue Op, SelectionDAG &DAG, bool LegalOperations, bool ForCodeSize,
904 NegatibleCost &Cost, unsigned Depth) const {
905
906 switch (Op.getOpcode()) {
907 case ISD::FMA:
908 case ISD::FMAD: {
909 // Negating a fma is not free if it has users without source mods.
910 if (!allUsesHaveSourceMods(Op.getNode()))
911 return SDValue();
912 break;
913 }
914 case AMDGPUISD::RCP: {
915 SDValue Src = Op.getOperand(0);
916 EVT VT = Op.getValueType();
917 SDLoc SL(Op);
918
919 SDValue NegSrc = getNegatedExpression(Src, DAG, LegalOperations,
920 ForCodeSize, Cost, Depth + 1);
921 if (NegSrc)
922 return DAG.getNode(AMDGPUISD::RCP, SL, VT, NegSrc, Op->getFlags());
923 return SDValue();
924 }
925 default:
926 break;
927 }
928
929 return TargetLowering::getNegatedExpression(Op, DAG, LegalOperations,
930 ForCodeSize, Cost, Depth);
931}
932
933//===---------------------------------------------------------------------===//
934// Target Properties
935//===---------------------------------------------------------------------===//
936
939
940 // Packed operations do not have a fabs modifier.
941 // Report this based on the end legalized type.
942 return VT == MVT::f32 || VT == MVT::f64 || VT == MVT::f16 || VT == MVT::bf16;
943}
944
947 // Report this based on the end legalized type.
948 VT = VT.getScalarType();
949 return VT == MVT::f32 || VT == MVT::f64 || VT == MVT::f16 || VT == MVT::bf16;
950}
951
953 unsigned NumElem,
954 unsigned AS) const {
955 return true;
956}
957
959 // There are few operations which truly have vector input operands. Any vector
960 // operation is going to involve operations on each component, and a
961 // build_vector will be a copy per element, so it always makes sense to use a
962 // build_vector input in place of the extracted element to avoid a copy into a
963 // super register.
964 //
965 // We should probably only do this if all users are extracts only, but this
966 // should be the common case.
967 return true;
968}
969
971 // Truncate is just accessing a subregister.
972
973 unsigned SrcSize = Source.getSizeInBits();
974 unsigned DestSize = Dest.getSizeInBits();
975
976 return DestSize < SrcSize && DestSize % 32 == 0 ;
977}
978
980 // Truncate is just accessing a subregister.
981
982 unsigned SrcSize = Source->getScalarSizeInBits();
983 unsigned DestSize = Dest->getScalarSizeInBits();
984
985 if (DestSize== 16 && Subtarget->has16BitInsts())
986 return SrcSize >= 32;
987
988 return DestSize < SrcSize && DestSize % 32 == 0;
989}
990
992 unsigned SrcSize = Src->getScalarSizeInBits();
993 unsigned DestSize = Dest->getScalarSizeInBits();
994
995 if (SrcSize == 16 && Subtarget->has16BitInsts())
996 return DestSize >= 32;
997
998 return SrcSize == 32 && DestSize == 64;
999}
1000
1002 // Any register load of a 64-bit value really requires 2 32-bit moves. For all
1003 // practical purposes, the extra mov 0 to load a 64-bit is free. As used,
1004 // this will enable reducing 64-bit operations the 32-bit, which is always
1005 // good.
1006
1007 if (Src == MVT::i16)
1008 return Dest == MVT::i32 ||Dest == MVT::i64 ;
1009
1010 return Src == MVT::i32 && Dest == MVT::i64;
1011}
1012
1014 EVT DestVT) const {
1015 switch (N->getOpcode()) {
1016 case ISD::ABS:
1017 case ISD::ADD:
1018 case ISD::SUB:
1019 case ISD::SHL:
1020 case ISD::SRL:
1021 case ISD::SRA:
1022 case ISD::AND:
1023 case ISD::OR:
1024 case ISD::XOR:
1025 case ISD::MUL:
1026 case ISD::SETCC:
1027 case ISD::SELECT:
1028 case ISD::SMIN:
1029 case ISD::SMAX:
1030 case ISD::UMIN:
1031 case ISD::UMAX:
1032 case ISD::USUBSAT:
1033 case ISD::UADDSAT:
1034 if (isTypeLegal(MVT::i16) &&
1035 (!DestVT.isVector() ||
1036 !isOperationLegal(ISD::ADD, MVT::v2i16))) { // Check if VOP3P
1037 // Don't narrow back down to i16 if promoted to i32 already.
1038 if (!N->isDivergent() && DestVT.isInteger() &&
1039 DestVT.getScalarSizeInBits() > 1 &&
1040 DestVT.getScalarSizeInBits() <= 16 &&
1041 SrcVT.getScalarSizeInBits() > 16) {
1042 return false;
1043 }
1044 }
1045 return true;
1046 default:
1047 break;
1048 }
1049
1050 // There aren't really 64-bit registers, but pairs of 32-bit ones and only a
1051 // limited number of native 64-bit operations. Shrinking an operation to fit
1052 // in a single 32-bit register should always be helpful. As currently used,
1053 // this is much less general than the name suggests, and is only used in
1054 // places trying to reduce the sizes of loads. Shrinking loads to < 32-bits is
1055 // not profitable, and may actually be harmful.
1056 if (isa<LoadSDNode>(N))
1057 return SrcVT.getSizeInBits() > 32 && DestVT.getSizeInBits() == 32;
1058
1059 return true;
1060}
1061
1063 const SDNode* N, CombineLevel Level) const {
1064 assert((N->getOpcode() == ISD::SHL || N->getOpcode() == ISD::SRA ||
1065 N->getOpcode() == ISD::SRL) &&
1066 "Expected shift op");
1067
1068 SDValue ShiftLHS = N->getOperand(0);
1069 if (!ShiftLHS->hasOneUse())
1070 return false;
1071
1072 if (ShiftLHS.getOpcode() == ISD::SIGN_EXTEND &&
1073 !ShiftLHS.getOperand(0)->hasOneUse())
1074 return false;
1075
1076 // Always commute pre-type legalization and right shifts.
1077 // We're looking for shl(or(x,y),z) patterns.
1079 N->getOpcode() != ISD::SHL || N->getOperand(0).getOpcode() != ISD::OR)
1080 return true;
1081
1082 // If only user is a i32 right-shift, then don't destroy a BFE pattern.
1083 if (N->getValueType(0) == MVT::i32 && N->hasOneUse() &&
1084 (N->user_begin()->getOpcode() == ISD::SRA ||
1085 N->user_begin()->getOpcode() == ISD::SRL))
1086 return false;
1087
1088 // Don't destroy or(shl(load_zext(),c), load_zext()) patterns.
1089 auto IsShiftAndLoad = [](SDValue LHS, SDValue RHS) {
1090 if (LHS.getOpcode() != ISD::SHL)
1091 return false;
1092 auto *RHSLd = dyn_cast<LoadSDNode>(RHS);
1093 auto *LHS0 = dyn_cast<LoadSDNode>(LHS.getOperand(0));
1094 auto *LHS1 = dyn_cast<ConstantSDNode>(LHS.getOperand(1));
1095 return LHS0 && LHS1 && RHSLd && LHS0->getExtensionType() == ISD::ZEXTLOAD &&
1096 LHS1->getAPIntValue() == LHS0->getMemoryVT().getScalarSizeInBits() &&
1097 RHSLd->getExtensionType() == ISD::ZEXTLOAD;
1098 };
1099 SDValue LHS = N->getOperand(0).getOperand(0);
1100 SDValue RHS = N->getOperand(0).getOperand(1);
1101 return !(IsShiftAndLoad(LHS, RHS) || IsShiftAndLoad(RHS, LHS));
1102}
1103
1104//===---------------------------------------------------------------------===//
1105// TargetLowering Callbacks
1106//===---------------------------------------------------------------------===//
1107
1109 bool IsVarArg) {
1110 switch (CC) {
1118 return CC_AMDGPU;
1121 return CC_AMDGPU_CS_CHAIN;
1122 case CallingConv::C:
1123 case CallingConv::Fast:
1124 case CallingConv::Cold:
1125 return CC_AMDGPU_Func;
1128 return CC_SI_Gfx;
1131 default:
1132 reportFatalUsageError("unsupported calling convention for call");
1133 }
1134}
1135
1137 bool IsVarArg) {
1138 switch (CC) {
1141 llvm_unreachable("kernels should not be handled here");
1151 return RetCC_SI_Shader;
1154 return RetCC_SI_Gfx;
1155 case CallingConv::C:
1156 case CallingConv::Fast:
1157 case CallingConv::Cold:
1158 return RetCC_AMDGPU_Func;
1159 default:
1160 reportFatalUsageError("unsupported calling convention");
1161 }
1162}
1163
1164/// The SelectionDAGBuilder will automatically promote function arguments
1165/// with illegal types. However, this does not work for the AMDGPU targets
1166/// since the function arguments are stored in memory as these illegal types.
1167/// In order to handle this properly we need to get the original types sizes
1168/// from the LLVM IR Function and fixup the ISD:InputArg values before
1169/// passing them to AnalyzeFormalArguments()
1170
1171/// When the SelectionDAGBuilder computes the Ins, it takes care of splitting
1172/// input values across multiple registers. Each item in the Ins array
1173/// represents a single value that will be stored in registers. Ins[x].VT is
1174/// the value type of the value that will be stored in the register, so
1175/// whatever SDNode we lower the argument to needs to be this type.
1176///
1177/// In order to correctly lower the arguments we need to know the size of each
1178/// argument. Since Ins[x].VT gives us the size of the register that will
1179/// hold the value, we need to look at Ins[x].ArgVT to see the 'real' type
1180/// for the original function argument so that we can deduce the correct memory
1181/// type to use for Ins[x]. In most cases the correct memory type will be
1182/// Ins[x].ArgVT. However, this will not always be the case. If, for example,
1183/// we have a kernel argument of type v8i8, this argument will be split into
1184/// 8 parts and each part will be represented by its own item in the Ins array.
1185/// For each part the Ins[x].ArgVT will be the v8i8, which is the full type of
1186/// the argument before it was split. From this, we deduce that the memory type
1187/// for each individual part is i8. We pass the memory type as LocVT to the
1188/// calling convention analysis function and the register type (Ins[x].VT) as
1189/// the ValVT.
1191 CCState &State,
1192 const SmallVectorImpl<ISD::InputArg> &Ins) const {
1193 const MachineFunction &MF = State.getMachineFunction();
1194 const Function &Fn = MF.getFunction();
1195 LLVMContext &Ctx = Fn.getContext();
1196 const unsigned ExplicitOffset = Subtarget->getExplicitKernelArgOffset();
1198
1199 Align MaxAlign = Align(1);
1200 uint64_t ExplicitArgOffset = 0;
1201 const DataLayout &DL = Fn.getDataLayout();
1202
1203 unsigned InIndex = 0;
1204
1205 for (const Argument &Arg : Fn.args()) {
1206 const bool IsByRef = Arg.hasByRefAttr();
1207 Type *BaseArgTy = Arg.getType();
1208 Type *MemArgTy = IsByRef ? Arg.getParamByRefType() : BaseArgTy;
1209 Align Alignment = DL.getValueOrABITypeAlignment(
1210 IsByRef ? Arg.getParamAlign() : std::nullopt, MemArgTy);
1211 MaxAlign = std::max(Alignment, MaxAlign);
1212 uint64_t AllocSize = DL.getTypeAllocSize(MemArgTy);
1213
1214 uint64_t ArgOffset = alignTo(ExplicitArgOffset, Alignment) + ExplicitOffset;
1215 ExplicitArgOffset = alignTo(ExplicitArgOffset, Alignment) + AllocSize;
1216
1217 // We're basically throwing away everything passed into us and starting over
1218 // to get accurate in-memory offsets. The "PartOffset" is completely useless
1219 // to us as computed in Ins.
1220 //
1221 // We also need to figure out what type legalization is trying to do to get
1222 // the correct memory offsets.
1223
1224 SmallVector<EVT, 16> ValueVTs;
1226 ComputeValueVTs(*this, DL, BaseArgTy, ValueVTs, /*MemVTs=*/nullptr,
1227 &Offsets, ArgOffset);
1228
1229 for (unsigned Value = 0, NumValues = ValueVTs.size();
1230 Value != NumValues; ++Value) {
1231 uint64_t BasePartOffset = Offsets[Value];
1232
1233 EVT ArgVT = ValueVTs[Value];
1234 EVT MemVT = ArgVT;
1235 MVT RegisterVT = getRegisterTypeForCallingConv(Ctx, CC, ArgVT);
1236 unsigned NumRegs = getNumRegistersForCallingConv(Ctx, CC, ArgVT);
1237
1238 if (NumRegs == 1) {
1239 // This argument is not split, so the IR type is the memory type.
1240 if (ArgVT.isExtended()) {
1241 // We have an extended type, like i24, so we should just use the
1242 // register type.
1243 MemVT = RegisterVT;
1244 } else {
1245 MemVT = ArgVT;
1246 }
1247 } else if (ArgVT.isVector() && RegisterVT.isVector() &&
1248 ArgVT.getScalarType() == RegisterVT.getScalarType()) {
1249 assert(ArgVT.getVectorNumElements() > RegisterVT.getVectorNumElements());
1250 // We have a vector value which has been split into a vector with
1251 // the same scalar type, but fewer elements. This should handle
1252 // all the floating-point vector types.
1253 MemVT = RegisterVT;
1254 } else if (ArgVT.isVector() &&
1255 ArgVT.getVectorNumElements() == NumRegs) {
1256 // This arg has been split so that each element is stored in a separate
1257 // register.
1258 MemVT = ArgVT.getScalarType();
1259 } else if (ArgVT.isExtended()) {
1260 // We have an extended type, like i65.
1261 MemVT = RegisterVT;
1262 } else {
1263 unsigned MemoryBits = ArgVT.getStoreSizeInBits() / NumRegs;
1264 assert(ArgVT.getStoreSizeInBits() % NumRegs == 0);
1265 if (RegisterVT.isInteger()) {
1266 MemVT = EVT::getIntegerVT(State.getContext(), MemoryBits);
1267 } else if (RegisterVT.isVector()) {
1268 assert(!RegisterVT.getScalarType().isFloatingPoint());
1269 unsigned NumElements = RegisterVT.getVectorNumElements();
1270 assert(MemoryBits % NumElements == 0);
1271 // This vector type has been split into another vector type with
1272 // a different elements size.
1273 EVT ScalarVT = EVT::getIntegerVT(State.getContext(),
1274 MemoryBits / NumElements);
1275 MemVT = EVT::getVectorVT(State.getContext(), ScalarVT, NumElements);
1276 } else {
1277 llvm_unreachable("cannot deduce memory type.");
1278 }
1279 }
1280
1281 // Convert one element vectors to scalar.
1282 if (MemVT.isVector() && MemVT.getVectorNumElements() == 1)
1283 MemVT = MemVT.getScalarType();
1284
1285 // Round up vec3/vec5 argument.
1286 if (MemVT.isVector() && !MemVT.isPow2VectorType()) {
1287 MemVT = MemVT.getPow2VectorType(State.getContext());
1288 } else if (!MemVT.isSimple() && !MemVT.isVector()) {
1289 MemVT = MemVT.getRoundIntegerType(State.getContext());
1290 }
1291
1292 unsigned PartOffset = 0;
1293 for (unsigned i = 0; i != NumRegs; ++i) {
1294 State.addLoc(CCValAssign::getCustomMem(InIndex++, RegisterVT,
1295 BasePartOffset + PartOffset,
1296 MemVT.getSimpleVT(),
1298 PartOffset += MemVT.getStoreSize();
1299 }
1300 }
1301 }
1302}
1303
1305 SDValue Chain, CallingConv::ID CallConv,
1306 bool isVarArg,
1308 const SmallVectorImpl<SDValue> &OutVals,
1309 const SDLoc &DL, SelectionDAG &DAG) const {
1310 // FIXME: Fails for r600 tests
1311 //assert(!isVarArg && Outs.empty() && OutVals.empty() &&
1312 // "wave terminate should not have return values");
1313 return DAG.getNode(AMDGPUISD::ENDPGM, DL, MVT::Other, Chain);
1314}
1315
1316//===---------------------------------------------------------------------===//
1317// Target specific lowering
1318//===---------------------------------------------------------------------===//
1319
1320/// Selects the correct CCAssignFn for a given CallingConvention value.
1325
1330
1332 SelectionDAG &DAG,
1333 MachineFrameInfo &MFI,
1334 int ClobberedFI) const {
1335 SmallVector<SDValue, 8> ArgChains;
1336 int64_t FirstByte = MFI.getObjectOffset(ClobberedFI);
1337 int64_t LastByte = FirstByte + MFI.getObjectSize(ClobberedFI) - 1;
1338
1339 // Include the original chain at the beginning of the list. When this is
1340 // used by target LowerCall hooks, this helps legalize find the
1341 // CALLSEQ_BEGIN node.
1342 ArgChains.push_back(Chain);
1343
1344 // Add a chain value for each stack argument corresponding
1345 for (SDNode *U : DAG.getEntryNode().getNode()->users()) {
1346 if (LoadSDNode *L = dyn_cast<LoadSDNode>(U)) {
1347 if (FrameIndexSDNode *FI = dyn_cast<FrameIndexSDNode>(L->getBasePtr())) {
1348 if (FI->getIndex() < 0) {
1349 int64_t InFirstByte = MFI.getObjectOffset(FI->getIndex());
1350 int64_t InLastByte = InFirstByte;
1351 InLastByte += MFI.getObjectSize(FI->getIndex()) - 1;
1352
1353 if ((InFirstByte <= FirstByte && FirstByte <= InLastByte) ||
1354 (FirstByte <= InFirstByte && InFirstByte <= LastByte))
1355 ArgChains.push_back(SDValue(L, 1));
1356 }
1357 }
1358 }
1359 }
1360
1361 // Build a tokenfactor for all the chains.
1362 return DAG.getNode(ISD::TokenFactor, SDLoc(Chain), MVT::Other, ArgChains);
1363}
1364
1367 StringRef Reason) const {
1368 SDValue Callee = CLI.Callee;
1369 SelectionDAG &DAG = CLI.DAG;
1370
1371 const Function &Fn = DAG.getMachineFunction().getFunction();
1372
1373 StringRef FuncName("<unknown>");
1374
1376 FuncName = G->getSymbol();
1377 else if (const GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee))
1378 FuncName = G->getGlobal()->getName();
1379
1380 DAG.getContext()->diagnose(
1381 DiagnosticInfoUnsupported(Fn, Reason + FuncName, CLI.DL.getDebugLoc()));
1382
1383 if (!CLI.IsTailCall) {
1384 for (ISD::InputArg &Arg : CLI.Ins)
1385 InVals.push_back(DAG.getPOISON(Arg.VT));
1386 }
1387
1388 // FIXME: Hack because R600 doesn't handle callseq pseudos yet.
1389 if (getTargetMachine().getTargetTriple().getArch() == Triple::r600)
1390 return CLI.Chain;
1391
1392 SDValue Chain = DAG.getCALLSEQ_START(CLI.Chain, 0, 0, CLI.DL);
1393 return DAG.getCALLSEQ_END(Chain, 0, 0, /*InGlue=*/SDValue(), CLI.DL);
1394}
1395
1397 SmallVectorImpl<SDValue> &InVals) const {
1398 return lowerUnhandledCall(CLI, InVals, "unsupported call to function ");
1399}
1400
1402 SelectionDAG &DAG) const {
1403 const Function &Fn = DAG.getMachineFunction().getFunction();
1404
1406 Fn, "unsupported dynamic alloca", SDLoc(Op).getDebugLoc()));
1407 auto Ops = {DAG.getConstant(0, SDLoc(), Op.getValueType()), Op.getOperand(0)};
1408 return DAG.getMergeValues(Ops, SDLoc());
1409}
1410
1412 SelectionDAG &DAG) const {
1413 switch (Op.getOpcode()) {
1414 default:
1415 Op->print(errs(), &DAG);
1416 llvm_unreachable("Custom lowering code for this "
1417 "instruction is not implemented yet!");
1418 break;
1420 case ISD::CONCAT_VECTORS: return LowerCONCAT_VECTORS(Op, DAG);
1422 case ISD::UDIVREM: return LowerUDIVREM(Op, DAG);
1423 case ISD::SDIVREM:
1424 return LowerSDIVREM(Op, DAG);
1425 case ISD::FCEIL: return LowerFCEIL(Op, DAG);
1426 case ISD::FTRUNC: return LowerFTRUNC(Op, DAG);
1427 case ISD::FRINT: return LowerFRINT(Op, DAG);
1428 case ISD::FNEARBYINT: return LowerFNEARBYINT(Op, DAG);
1429 case ISD::FROUNDEVEN:
1430 return LowerFROUNDEVEN(Op, DAG);
1431 case ISD::FROUND: return LowerFROUND(Op, DAG);
1432 case ISD::FFLOOR: return LowerFFLOOR(Op, DAG);
1433 case ISD::FLOG2:
1434 return LowerFLOG2(Op, DAG);
1435 case ISD::FLOG:
1436 case ISD::FLOG10:
1437 return LowerFLOGCommon(Op, DAG);
1438 case ISD::FEXP:
1439 case ISD::FEXP10:
1440 return lowerFEXP(Op, DAG);
1441 case ISD::FEXP2:
1442 return lowerFEXP2(Op, DAG);
1443 case ISD::FPOW:
1444 return lowerFPOW(Op, DAG);
1445 case ISD::SINT_TO_FP: return LowerSINT_TO_FP(Op, DAG);
1446 case ISD::UINT_TO_FP: return LowerUINT_TO_FP(Op, DAG);
1447 case ISD::FP_TO_FP16: return LowerFP_TO_FP16(Op, DAG);
1448 case ISD::FP_TO_SINT:
1449 case ISD::FP_TO_UINT:
1450 return LowerFP_TO_INT(Op, DAG);
1453 return LowerFP_TO_INT_SAT(Op, DAG);
1454 case ISD::CTTZ:
1456 case ISD::CTLZ:
1458 return LowerCTLZ_CTTZ(Op, DAG);
1459 case ISD::CTLS:
1460 return LowerCTLS(Op, DAG);
1462 }
1463 return Op;
1464}
1465
1468 SelectionDAG &DAG) const {
1469 switch (N->getOpcode()) {
1471 // Different parts of legalization seem to interpret which type of
1472 // sign_extend_inreg is the one to check for custom lowering. The extended
1473 // from type is what really matters, but some places check for custom
1474 // lowering of the result type. This results in trying to use
1475 // ReplaceNodeResults to sext_in_reg to an illegal type, so we'll just do
1476 // nothing here and let the illegal result integer be handled normally.
1477 return;
1478 case ISD::FLOG2:
1479 if (SDValue Lowered = LowerFLOG2(SDValue(N, 0), DAG))
1480 Results.push_back(Lowered);
1481 return;
1482 case ISD::FLOG:
1483 case ISD::FLOG10:
1484 if (SDValue Lowered = LowerFLOGCommon(SDValue(N, 0), DAG))
1485 Results.push_back(Lowered);
1486 return;
1487 case ISD::FEXP2:
1488 if (SDValue Lowered = lowerFEXP2(SDValue(N, 0), DAG))
1489 Results.push_back(Lowered);
1490 return;
1491 case ISD::FEXP:
1492 case ISD::FEXP10:
1493 if (SDValue Lowered = lowerFEXP(SDValue(N, 0), DAG))
1494 Results.push_back(Lowered);
1495 return;
1496 case ISD::CTLZ:
1498 if (auto Lowered = lowerCTLZResults(SDValue(N, 0u), DAG))
1499 Results.push_back(Lowered);
1500 return;
1501 default:
1502 return;
1503 }
1504}
1505
1507 SelectionDAG &DAG) const {
1509 SDLoc SL(Op);
1510 EVT VT = Op.getValueType();
1511 return DAG.getTargetBlockAddress(BA->getBlockAddress(), VT, BA->getOffset(),
1512 BA->getTargetFlags());
1513}
1514
1516 SDValue Op,
1517 SelectionDAG &DAG) const {
1518
1519 const DataLayout &DL = DAG.getDataLayout();
1521 const GlobalValue *GV = G->getGlobal();
1522
1523 if (G->getAddressSpace() == AMDGPUAS::BARRIER) {
1524 const GlobalVariable *GVar = cast<GlobalVariable>(GV);
1525
1526 if (!AMDGPU::isNamedBarrier(*GVar)) {
1527 const Function &Fn = DAG.getMachineFunction().getFunction();
1529 Fn, "unsupported use of BARRIER address space",
1531 return DAG.getPOISON(Op.getValueType());
1532 }
1533
1534 unsigned Offset = MFI->allocateBarrierGlobal(DL, *cast<GlobalVariable>(GV));
1535 return DAG.getConstant(Offset, SDLoc(Op), Op.getValueType());
1536 }
1537
1538 if (!MFI->isModuleEntryFunction()) {
1539 if (std::optional<uint32_t> Address =
1542 return DAG.getConstant(*Address, SDLoc(Op), Op.getValueType());
1543 }
1544 }
1545
1546 if (G->getAddressSpace() == AMDGPUAS::LOCAL_ADDRESS ||
1547 G->getAddressSpace() == AMDGPUAS::REGION_ADDRESS) {
1548 if (!MFI->isModuleEntryFunction() &&
1549 GV->getName() != "llvm.amdgcn.module.lds") {
1550 SDLoc DL(Op);
1551 const Function &Fn = DAG.getMachineFunction().getFunction();
1553 Fn, "local memory global used by non-kernel function",
1554 DL.getDebugLoc(), DS_Warning));
1555
1556 // We currently don't have a way to correctly allocate LDS objects that
1557 // aren't directly associated with a kernel. We do force inlining of
1558 // functions that use local objects. However, if these dead functions are
1559 // not eliminated, we don't want a compile time error. Just emit a warning
1560 // and a trap, since there should be no callable path here.
1561 SDValue Trap = DAG.getNode(ISD::TRAP, DL, MVT::Other, DAG.getEntryNode());
1562 SDValue OutputChain = DAG.getNode(ISD::TokenFactor, DL, MVT::Other,
1563 Trap, DAG.getRoot());
1564 DAG.setRoot(OutputChain);
1565 return DAG.getPOISON(Op.getValueType());
1566 }
1567
1568 // TODO: We could emit code to handle the initialization somewhere.
1569 // We ignore the initializer for now and legalize it to allow selection.
1570 // The initializer will anyway get errored out during assembly emission.
1571 unsigned Offset = MFI->allocateLDSGlobal(DL, *cast<GlobalVariable>(GV));
1572 // A constant byte offset (e.g. from a GEP into an array of named barriers)
1573 // folds directly into the allocated LDS address.
1574 return DAG.getConstant(Offset + G->getOffset(), SDLoc(Op),
1575 Op.getValueType());
1576 }
1577 return SDValue();
1578}
1579
1581 SelectionDAG &DAG) const {
1583 SDLoc SL(Op);
1584
1585 EVT VT = Op.getValueType();
1586 if (VT.getVectorElementType().getSizeInBits() < 32) {
1587 unsigned OpBitSize = Op.getOperand(0).getValueType().getSizeInBits();
1588 if (OpBitSize >= 32 && OpBitSize % 32 == 0) {
1589 unsigned NewNumElt = OpBitSize / 32;
1590 EVT NewEltVT = (NewNumElt == 1) ? MVT::i32
1592 MVT::i32, NewNumElt);
1593 for (const SDUse &U : Op->ops()) {
1594 SDValue In = U.get();
1595 SDValue NewIn = DAG.getNode(ISD::BITCAST, SL, NewEltVT, In);
1596 if (NewNumElt > 1)
1597 DAG.ExtractVectorElements(NewIn, Args);
1598 else
1599 Args.push_back(NewIn);
1600 }
1601
1602 EVT NewVT = EVT::getVectorVT(*DAG.getContext(), MVT::i32,
1603 NewNumElt * Op.getNumOperands());
1604 SDValue BV = DAG.getBuildVector(NewVT, SL, Args);
1605 return DAG.getNode(ISD::BITCAST, SL, VT, BV);
1606 }
1607 }
1608
1609 for (const SDUse &U : Op->ops())
1610 DAG.ExtractVectorElements(U.get(), Args);
1611
1612 return DAG.getBuildVector(Op.getValueType(), SL, Args);
1613}
1614
1616 SelectionDAG &DAG) const {
1617 SDLoc SL(Op);
1619 unsigned Start = Op.getConstantOperandVal(1);
1620 EVT VT = Op.getValueType();
1621 EVT SrcVT = Op.getOperand(0).getValueType();
1622
1623 if (VT.getScalarSizeInBits() == 16 && Start % 2 == 0) {
1624 unsigned NumElt = VT.getVectorNumElements();
1625 unsigned NumSrcElt = SrcVT.getVectorNumElements();
1626 assert(NumElt % 2 == 0 && NumSrcElt % 2 == 0 && "expect legal types");
1627
1628 // Extract 32-bit registers at a time.
1629 EVT NewSrcVT = EVT::getVectorVT(*DAG.getContext(), MVT::i32, NumSrcElt / 2);
1630 EVT NewVT = NumElt == 2
1631 ? MVT::i32
1632 : EVT::getVectorVT(*DAG.getContext(), MVT::i32, NumElt / 2);
1633 SDValue Tmp = DAG.getNode(ISD::BITCAST, SL, NewSrcVT, Op.getOperand(0));
1634
1635 DAG.ExtractVectorElements(Tmp, Args, Start / 2, NumElt / 2);
1636 if (NumElt == 2)
1637 Tmp = Args[0];
1638 else
1639 Tmp = DAG.getBuildVector(NewVT, SL, Args);
1640
1641 return DAG.getNode(ISD::BITCAST, SL, VT, Tmp);
1642 }
1643
1644 DAG.ExtractVectorElements(Op.getOperand(0), Args, Start,
1646
1647 return DAG.getBuildVector(Op.getValueType(), SL, Args);
1648}
1649
1650// TODO: Handle fabs too
1652 if (Val.getOpcode() == ISD::FNEG)
1653 return Val.getOperand(0);
1654
1655 return Val;
1656}
1657
1658// SelectionDAG twin of AMDGPUCombinerHelper::canIgnoreLegacyMinMaxTies.
1660 SDNodeFlags Flags, SDValue LHS,
1661 SDValue RHS) {
1662 return Flags.hasNoSignedZeros() || DAG.isKnownNeverLogicalZero(LHS) ||
1664}
1665
1667 const SDLoc &DL, EVT VT, SDValue LHS, SDValue RHS, SDValue True,
1668 SDValue False, SDValue CC, SDNodeFlags Flags, DAGCombinerInfo &DCI) const {
1669 SelectionDAG &DAG = DCI.DAG;
1670 ISD::CondCode CCOpcode = cast<CondCodeSDNode>(CC)->get();
1671 assert(CCOpcode != ISD::SETCC_INVALID && "Invalid setcc condcode!");
1672
1673 switch (CCOpcode) {
1674 case ISD::SETOLE:
1675 case ISD::SETOLT:
1676 case ISD::SETLE:
1677 case ISD::SETLT:
1678 case ISD::SETOGE:
1679 case ISD::SETOGT:
1680 case ISD::SETGE:
1681 case ISD::SETGT:
1682 // Only do this after legalization to avoid interfering with other combines
1683 // which might occur.
1685 !DCI.isCalledByLegalizer())
1686 return SDValue();
1687 break;
1688 default:
1689 break;
1690 }
1691
1692 // Canonicalize so the select returns the compare's LHS on a true predicate.
1693 if (LHS != True)
1694 CCOpcode = ISD::getSetCCInverse(CCOpcode, VT);
1695
1696 unsigned Opc;
1697 bool Swap; // Emit (rhs, lhs) instead of (lhs, rhs).
1698 switch (CCOpcode) {
1699 case ISD::SETOLT:
1700 case ISD::SETLT:
1701 case ISD::SETOLE:
1702 Opc = AMDGPUISD::FMIN_LEGACY;
1703 Swap = false;
1704 break;
1705 case ISD::SETULE:
1706 case ISD::SETLE:
1707 case ISD::SETULT:
1708 Opc = AMDGPUISD::FMIN_LEGACY;
1709 Swap = true;
1710 break;
1711 case ISD::SETOGE:
1712 case ISD::SETGE:
1713 case ISD::SETOGT:
1714 Opc = AMDGPUISD::FMAX_LEGACY;
1715 Swap = false;
1716 break;
1717 case ISD::SETUGT:
1718 case ISD::SETGT:
1719 case ISD::SETUGE:
1720 Opc = AMDGPUISD::FMAX_LEGACY;
1721 Swap = true;
1722 break;
1723 default:
1724 return SDValue();
1725 }
1726
1727 // For these predicates the NaN-correct operand order is the signed zero
1728 // tie-incorrect one, so the fold needs the tie to be unobservable.
1729 if ((CCOpcode == ISD::SETOLE || CCOpcode == ISD::SETULT ||
1730 CCOpcode == ISD::SETOGT || CCOpcode == ISD::SETUGE) &&
1731 !canIgnoreLegacyMinMaxTies(DAG, Flags, LHS, RHS))
1732 return SDValue();
1733
1734 if (Swap)
1735 std::swap(LHS, RHS);
1736 return DAG.getNode(Opc, DL, VT, LHS, RHS, Flags);
1737}
1738
1739/// Generate Min/Max node
1741 const SDLoc &DL, EVT VT, SDValue LHS, SDValue RHS, SDValue True,
1742 SDValue False, SDValue CC, SDNodeFlags Flags, DAGCombinerInfo &DCI) const {
1743 if ((LHS == True && RHS == False) || (LHS == False && RHS == True))
1744 return combineFMinMaxLegacyImpl(DL, VT, LHS, RHS, True, False, CC, Flags,
1745 DCI);
1746
1747 SelectionDAG &DAG = DCI.DAG;
1748
1749 // If we can't directly match this, try to see if we can fold an fneg to
1750 // match.
1751
1754 SDValue NegTrue = peekFNeg(True);
1755
1756 // Undo the combine foldFreeOpFromSelect does if it helps us match the
1757 // fmin/fmax.
1758 //
1759 // select (fcmp olt (lhs, K)), (fneg lhs), -K
1760 // -> fneg (fmin_legacy lhs, K)
1761 //
1762 // TODO: Use getNegatedExpression
1763 if (LHS == NegTrue && CFalse && CRHS) {
1764 APFloat NegRHS = neg(CRHS->getValueAPF());
1765 if (NegRHS == CFalse->getValueAPF()) {
1766 SDValue Combined = combineFMinMaxLegacyImpl(DL, VT, LHS, RHS, NegTrue,
1767 False, CC, Flags, DCI);
1768 if (Combined)
1769 return DAG.getNode(ISD::FNEG, DL, VT, Combined);
1770 return SDValue();
1771 }
1772 }
1773
1774 return SDValue();
1775}
1776
1777std::pair<SDValue, SDValue>
1779 SDLoc SL(Op);
1780
1781 SDValue Vec = DAG.getNode(ISD::BITCAST, SL, MVT::v2i32, Op);
1782
1783 const SDValue Zero = DAG.getConstant(0, SL, MVT::i32);
1784 const SDValue One = DAG.getConstant(1, SL, MVT::i32);
1785
1786 SDValue Lo = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, SL, MVT::i32, Vec, Zero);
1787 SDValue Hi = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, SL, MVT::i32, Vec, One);
1788
1789 return std::pair(Lo, Hi);
1790}
1791
1793 SDLoc SL(Op);
1794
1795 SDValue Vec = DAG.getNode(ISD::BITCAST, SL, MVT::v2i32, Op);
1796 const SDValue One = DAG.getConstant(1, SL, MVT::i32);
1797 return DAG.getNode(ISD::EXTRACT_VECTOR_ELT, SL, MVT::i32, Vec, One);
1798}
1799
1800// Split a vector type into two parts. The first part is a power of two vector.
1801// The second part is whatever is left over, and is a scalar if it would
1802// otherwise be a 1-vector.
1803std::pair<EVT, EVT>
1805 EVT LoVT, HiVT;
1806 EVT EltVT = VT.getVectorElementType();
1807 unsigned NumElts = VT.getVectorNumElements();
1808 unsigned LoNumElts = PowerOf2Ceil((NumElts + 1) / 2);
1809 LoVT = EVT::getVectorVT(*DAG.getContext(), EltVT, LoNumElts);
1810 HiVT = NumElts - LoNumElts == 1
1811 ? EltVT
1812 : EVT::getVectorVT(*DAG.getContext(), EltVT, NumElts - LoNumElts);
1813 return std::pair(LoVT, HiVT);
1814}
1815
1816// Split a vector value into two parts of types LoVT and HiVT. HiVT could be
1817// scalar.
1818std::pair<SDValue, SDValue>
1820 const EVT &LoVT, const EVT &HiVT,
1821 SelectionDAG &DAG) const {
1822 EVT VT = N.getValueType();
1824 (HiVT.isVector() ? HiVT.getVectorNumElements() : 1) <=
1825 VT.getVectorNumElements() &&
1826 "More vector elements requested than available!");
1828 DAG.getVectorIdxConstant(0, DL));
1829
1830 unsigned LoNumElts = LoVT.getVectorNumElements();
1831
1832 if (HiVT.isVector()) {
1833 unsigned HiNumElts = HiVT.getVectorNumElements();
1834 if ((VT.getVectorNumElements() % HiNumElts) == 0) {
1835 // Avoid creating an extract_subvector with an index that isn't a multiple
1836 // of the result type.
1838 DAG.getConstant(LoNumElts, DL, MVT::i32));
1839 return {Lo, Hi};
1840 }
1841
1843 DAG.ExtractVectorElements(N, Elts, /*Start=*/LoNumElts,
1844 /*Count=*/HiNumElts);
1845 SDValue Hi = DAG.getBuildVector(HiVT, DL, Elts);
1846 return {Lo, Hi};
1847 }
1848
1850 DAG.getVectorIdxConstant(LoNumElts, DL));
1851 return {Lo, Hi};
1852}
1853
1855 SelectionDAG &DAG) const {
1857 EVT VT = Op.getValueType();
1858 SDLoc SL(Op);
1859
1860
1861 // If this is a 2 element vector, we really want to scalarize and not create
1862 // weird 1 element vectors.
1863 if (VT.getVectorNumElements() == 2) {
1864 SDValue Ops[2];
1865 std::tie(Ops[0], Ops[1]) = scalarizeVectorLoad(Load, DAG);
1866 return DAG.getMergeValues(Ops, SL);
1867 }
1868
1869 SDValue BasePtr = Load->getBasePtr();
1870 EVT MemVT = Load->getMemoryVT();
1871
1872 const MachinePointerInfo &SrcValue = Load->getMemOperand()->getPointerInfo();
1873
1874 EVT LoVT, HiVT;
1875 EVT LoMemVT, HiMemVT;
1876 SDValue Lo, Hi;
1877
1878 std::tie(LoVT, HiVT) = getSplitDestVTs(VT, DAG);
1879 std::tie(LoMemVT, HiMemVT) = getSplitDestVTs(MemVT, DAG);
1880 std::tie(Lo, Hi) = splitVector(Op, SL, LoVT, HiVT, DAG);
1881
1882 unsigned Size = LoMemVT.getStoreSize();
1883 Align BaseAlign = Load->getAlign();
1884 Align HiAlign = commonAlignment(BaseAlign, Size);
1885
1886 SDValue LoLoad = DAG.getExtLoad(
1887 Load->getExtensionType(), SL, LoVT, Load->getChain(), BasePtr, SrcValue,
1888 LoMemVT, BaseAlign, Load->getMemOperand()->getFlags(), Load->getAAInfo());
1889 SDValue HiPtr = DAG.getObjectPtrOffset(SL, BasePtr, TypeSize::getFixed(Size));
1890 SDValue HiLoad = DAG.getExtLoad(
1891 Load->getExtensionType(), SL, HiVT, Load->getChain(), HiPtr,
1892 SrcValue.getWithOffset(LoMemVT.getStoreSize()), HiMemVT, HiAlign,
1893 Load->getMemOperand()->getFlags(), Load->getAAInfo());
1894
1895 SDValue Join;
1896 if (LoVT == HiVT) {
1897 // This is the case that the vector is power of two so was evenly split.
1898 Join = DAG.getNode(ISD::CONCAT_VECTORS, SL, VT, LoLoad, HiLoad);
1899 } else {
1900 Join = DAG.getNode(ISD::INSERT_SUBVECTOR, SL, VT, DAG.getPOISON(VT), LoLoad,
1901 DAG.getVectorIdxConstant(0, SL));
1902 Join = DAG.getNode(
1904 VT, Join, HiLoad,
1906 }
1907
1908 SDValue Ops[] = {Join, DAG.getNode(ISD::TokenFactor, SL, MVT::Other,
1909 LoLoad.getValue(1), HiLoad.getValue(1))};
1910
1911 return DAG.getMergeValues(Ops, SL);
1912}
1913
1915 SelectionDAG &DAG) const {
1917 EVT VT = Op.getValueType();
1918 SDValue BasePtr = Load->getBasePtr();
1919 EVT MemVT = Load->getMemoryVT();
1920 SDLoc SL(Op);
1921 const MachinePointerInfo &SrcValue = Load->getMemOperand()->getPointerInfo();
1922 Align BaseAlign = Load->getAlign();
1923 unsigned NumElements = MemVT.getVectorNumElements();
1924
1925 // Widen from vec3 to vec4 when the load is at least 8-byte aligned
1926 // or 16-byte fully dereferenceable. Otherwise, split the vector load.
1927 if (NumElements != 3 ||
1928 (BaseAlign < Align(8) &&
1929 !SrcValue.isDereferenceable(16, *DAG.getContext(), DAG.getDataLayout())))
1930 return SplitVectorLoad(Op, DAG);
1931
1932 assert(NumElements == 3);
1933
1934 EVT WideVT =
1936 EVT WideMemVT =
1938 SDValue WideLoad = DAG.getExtLoad(
1939 Load->getExtensionType(), SL, WideVT, Load->getChain(), BasePtr, SrcValue,
1940 WideMemVT, BaseAlign, Load->getMemOperand()->getFlags());
1941 return DAG.getMergeValues(
1942 {DAG.getNode(ISD::EXTRACT_SUBVECTOR, SL, VT, WideLoad,
1943 DAG.getVectorIdxConstant(0, SL)),
1944 WideLoad.getValue(1)},
1945 SL);
1946}
1947
1949 SelectionDAG &DAG) const {
1951 SDValue Val = Store->getValue();
1952 EVT VT = Val.getValueType();
1953
1954 // If this is a 2 element vector, we really want to scalarize and not create
1955 // weird 1 element vectors.
1956 if (VT.getVectorNumElements() == 2)
1957 return scalarizeVectorStore(Store, DAG);
1958
1959 EVT MemVT = Store->getMemoryVT();
1960 SDValue Chain = Store->getChain();
1961 SDValue BasePtr = Store->getBasePtr();
1962 SDLoc SL(Op);
1963
1964 EVT LoVT, HiVT;
1965 EVT LoMemVT, HiMemVT;
1966 SDValue Lo, Hi;
1967
1968 std::tie(LoVT, HiVT) = getSplitDestVTs(VT, DAG);
1969 std::tie(LoMemVT, HiMemVT) = getSplitDestVTs(MemVT, DAG);
1970 std::tie(Lo, Hi) = splitVector(Val, SL, LoVT, HiVT, DAG);
1971
1972 SDValue HiPtr = DAG.getObjectPtrOffset(SL, BasePtr, LoMemVT.getStoreSize());
1973
1974 const MachinePointerInfo &SrcValue = Store->getMemOperand()->getPointerInfo();
1975 Align BaseAlign = Store->getAlign();
1976 unsigned Size = LoMemVT.getStoreSize();
1977 Align HiAlign = commonAlignment(BaseAlign, Size);
1978
1979 SDValue LoStore =
1980 DAG.getTruncStore(Chain, SL, Lo, BasePtr, SrcValue, LoMemVT, BaseAlign,
1981 Store->getMemOperand()->getFlags(), Store->getAAInfo());
1982 SDValue HiStore = DAG.getTruncStore(
1983 Chain, SL, Hi, HiPtr, SrcValue.getWithOffset(Size), HiMemVT, HiAlign,
1984 Store->getMemOperand()->getFlags(), Store->getAAInfo());
1985
1986 return DAG.getNode(ISD::TokenFactor, SL, MVT::Other, LoStore, HiStore);
1987}
1988
1989// This is a shortcut for integer division because we have fast i32<->f32
1990// conversions, and fast f32 reciprocal instructions.
1992 bool Sign) const {
1993 SDLoc DL(Op);
1994 EVT VT = Op.getValueType();
1995 assert(VT == MVT::i32 && "LowerDIVREMToFloat expects an i32");
1996
1997 SDValue LHS = Op.getOperand(0);
1998 SDValue RHS = Op.getOperand(1);
1999 MVT IntVT = MVT::i32;
2000 MVT FltVT = MVT::f32;
2001
2002 unsigned LHSSignBits;
2003 unsigned RHSSignBits;
2004 if (Sign) {
2005 LHSSignBits = DAG.ComputeNumSignBits(LHS);
2006 RHSSignBits = DAG.ComputeNumSignBits(RHS);
2007 if (LHSSignBits < 9 || RHSSignBits < 9)
2008 return SDValue();
2009 } else {
2010 KnownBits LHSKnown = DAG.computeKnownBits(LHS);
2011 KnownBits RHSKnown = DAG.computeKnownBits(RHS);
2012
2013 LHSSignBits = LHSKnown.countMinLeadingZeros();
2014 RHSSignBits = RHSKnown.countMinLeadingZeros();
2015 }
2016
2017 unsigned BitSize = VT.getSizeInBits();
2018 unsigned SignBits = std::min(LHSSignBits, RHSSignBits);
2019 unsigned DivBits = BitSize - SignBits;
2020 if (Sign)
2021 ++DivBits;
2022
2023 // In order to avoid problems due to 1 ulp accuracy issues with v_rcp_f32,
2024 // limit LowerDIVREMToFloat to:
2025 // [-0x400000,0x3FFFFF] for Sign
2026 // [ 0x000000,0x3FFFFF] for !Sign
2027 // This matches what is done in expandDivRemToFloatImpl.
2028 if (DivBits > (Sign ? 23 : 22))
2029 return SDValue();
2030
2033
2034 // int ia = (int)LHS;
2035 SDValue ia = LHS;
2036
2037 // int ib, (int)RHS;
2038 SDValue ib = RHS;
2039
2040 // The calculation:
2041 // fq = fa*recip(fb)
2042 // may be too small due to the 1ulp accuracy in the recip
2043 // operation and rounding issues. Since fq is truncated to produce
2044 // an integer value it may be too small by one. This is
2045 // dealt with by incrementing fa by 1ulp:
2046 // fq = (fa+1ulp)*recip(fb)
2047 // This will increase fa's magnitude by at most 0.5
2048 // (i.e. when fabs(fa)==0x400000 the LSB of the mantissa represents 0.5).
2049 // Thus, this method is safe since fa must be incremented by at least 1.0
2050 // for the quotient to increase by one.
2051 SDValue fa = DAG.getNode(ToFp, DL, FltVT, ia);
2052 SDValue faAsInt = DAG.getNode(ISD::BITCAST, DL, MVT::i32, fa);
2053 SDValue faIncremented = DAG.getNode(ISD::ADD, DL, MVT::i32, faAsInt,
2054 DAG.getConstant(1, DL, MVT::i32));
2055 fa = DAG.getNode(ISD::BITCAST, DL, FltVT, faIncremented);
2056
2057 // float fb = (float)ib;
2058 SDValue fb = DAG.getNode(ToFp, DL, FltVT, ib);
2059
2060 SDValue fq = DAG.getNode(ISD::FMUL, DL, FltVT,
2061 fa, DAG.getNode(AMDGPUISD::RCP, DL, FltVT, fb));
2062
2063 // fq = trunc(fq);
2064 fq = DAG.getNode(ISD::FTRUNC, DL, FltVT, fq);
2065
2066 // int iq = (int)fq;
2067 SDValue Div = DAG.getNode(ToInt, DL, IntVT, fq);
2068
2069 // Rem needs compensation, it's easier to recompute it
2070 SDValue Rem = DAG.getNode(ISD::MUL, DL, VT, Div, RHS);
2071 Rem = DAG.getNode(ISD::SUB, DL, VT, LHS, Rem);
2072
2073 return DAG.getMergeValues({ Div, Rem }, DL);
2074}
2075
2077 SelectionDAG &DAG,
2079 SDLoc DL(Op);
2080 EVT VT = Op.getValueType();
2081
2082 assert(VT == MVT::i64 && "LowerUDIVREM64 expects an i64");
2083
2084 EVT HalfVT = VT.getHalfSizedIntegerVT(*DAG.getContext());
2085
2086 SDValue One = DAG.getConstant(1, DL, HalfVT);
2087 SDValue Zero = DAG.getConstant(0, DL, HalfVT);
2088
2089 //HiLo split
2090 SDValue LHS_Lo, LHS_Hi;
2091 SDValue LHS = Op.getOperand(0);
2092 std::tie(LHS_Lo, LHS_Hi) = DAG.SplitScalar(LHS, DL, HalfVT, HalfVT);
2093
2094 SDValue RHS_Lo, RHS_Hi;
2095 SDValue RHS = Op.getOperand(1);
2096 std::tie(RHS_Lo, RHS_Hi) = DAG.SplitScalar(RHS, DL, HalfVT, HalfVT);
2097
2098 if (DAG.MaskedValueIsZero(RHS, APInt::getHighBitsSet(64, 32)) &&
2099 DAG.MaskedValueIsZero(LHS, APInt::getHighBitsSet(64, 32))) {
2100
2101 SDValue Res = DAG.getNode(ISD::UDIVREM, DL, DAG.getVTList(HalfVT, HalfVT),
2102 LHS_Lo, RHS_Lo);
2103
2104 SDValue DIV = DAG.getBuildVector(MVT::v2i32, DL, {Res.getValue(0), Zero});
2105 SDValue REM = DAG.getBuildVector(MVT::v2i32, DL, {Res.getValue(1), Zero});
2106
2107 Results.push_back(DAG.getNode(ISD::BITCAST, DL, MVT::i64, DIV));
2108 Results.push_back(DAG.getNode(ISD::BITCAST, DL, MVT::i64, REM));
2109 return;
2110 }
2111
2112 if (isTypeLegal(MVT::i64)) {
2113 // The algorithm here is based on ideas from "Software Integer Division",
2114 // Tom Rodeheffer, August 2008.
2115
2118
2119 // Compute denominator reciprocal.
2120 unsigned FMAD =
2121 !Subtarget->hasMadMacF32Insts() ? (unsigned)ISD::FMA
2124 : (unsigned)AMDGPUISD::FMAD_FTZ;
2125
2126 SDValue Cvt_Lo = DAG.getNode(ISD::UINT_TO_FP, DL, MVT::f32, RHS_Lo);
2127 SDValue Cvt_Hi = DAG.getNode(ISD::UINT_TO_FP, DL, MVT::f32, RHS_Hi);
2128 SDValue Mad1 = DAG.getNode(FMAD, DL, MVT::f32, Cvt_Hi,
2129 DAG.getConstantFP(APInt(32, 0x4f800000).bitsToFloat(), DL, MVT::f32),
2130 Cvt_Lo);
2131 SDValue Rcp = DAG.getNode(AMDGPUISD::RCP, DL, MVT::f32, Mad1);
2132 SDValue Mul1 = DAG.getNode(ISD::FMUL, DL, MVT::f32, Rcp,
2133 DAG.getConstantFP(APInt(32, 0x5f7ffffc).bitsToFloat(), DL, MVT::f32));
2134 SDValue Mul2 = DAG.getNode(ISD::FMUL, DL, MVT::f32, Mul1,
2135 DAG.getConstantFP(APInt(32, 0x2f800000).bitsToFloat(), DL, MVT::f32));
2136 SDValue Trunc = DAG.getNode(ISD::FTRUNC, DL, MVT::f32, Mul2);
2137 SDValue Mad2 = DAG.getNode(FMAD, DL, MVT::f32, Trunc,
2138 DAG.getConstantFP(APInt(32, 0xcf800000).bitsToFloat(), DL, MVT::f32),
2139 Mul1);
2140 SDValue Rcp_Lo = DAG.getNode(ISD::FP_TO_UINT, DL, HalfVT, Mad2);
2141 SDValue Rcp_Hi = DAG.getNode(ISD::FP_TO_UINT, DL, HalfVT, Trunc);
2142 SDValue Rcp64 = DAG.getBitcast(VT,
2143 DAG.getBuildVector(MVT::v2i32, DL, {Rcp_Lo, Rcp_Hi}));
2144
2145 SDValue Zero64 = DAG.getConstant(0, DL, VT);
2146 SDValue One64 = DAG.getConstant(1, DL, VT);
2147 SDValue Zero1 = DAG.getConstant(0, DL, MVT::i1);
2148 SDVTList HalfCarryVT = DAG.getVTList(HalfVT, MVT::i1);
2149
2150 // First round of UNR (Unsigned integer Newton-Raphson).
2151 SDValue Neg_RHS = DAG.getNode(ISD::SUB, DL, VT, Zero64, RHS);
2152 SDValue Mullo1 = DAG.getNode(ISD::MUL, DL, VT, Neg_RHS, Rcp64);
2153 SDValue Mulhi1 = DAG.getNode(ISD::MULHU, DL, VT, Rcp64, Mullo1);
2154 SDValue Mulhi1_Lo, Mulhi1_Hi;
2155 std::tie(Mulhi1_Lo, Mulhi1_Hi) =
2156 DAG.SplitScalar(Mulhi1, DL, HalfVT, HalfVT);
2157 SDValue Add1_Lo = DAG.getNode(ISD::UADDO_CARRY, DL, HalfCarryVT, Rcp_Lo,
2158 Mulhi1_Lo, Zero1);
2159 SDValue Add1_Hi = DAG.getNode(ISD::UADDO_CARRY, DL, HalfCarryVT, Rcp_Hi,
2160 Mulhi1_Hi, Add1_Lo.getValue(1));
2161 SDValue Add1 = DAG.getBitcast(VT,
2162 DAG.getBuildVector(MVT::v2i32, DL, {Add1_Lo, Add1_Hi}));
2163
2164 // Second round of UNR.
2165 SDValue Mullo2 = DAG.getNode(ISD::MUL, DL, VT, Neg_RHS, Add1);
2166 SDValue Mulhi2 = DAG.getNode(ISD::MULHU, DL, VT, Add1, Mullo2);
2167 SDValue Mulhi2_Lo, Mulhi2_Hi;
2168 std::tie(Mulhi2_Lo, Mulhi2_Hi) =
2169 DAG.SplitScalar(Mulhi2, DL, HalfVT, HalfVT);
2170 SDValue Add2_Lo = DAG.getNode(ISD::UADDO_CARRY, DL, HalfCarryVT, Add1_Lo,
2171 Mulhi2_Lo, Zero1);
2172 SDValue Add2_Hi = DAG.getNode(ISD::UADDO_CARRY, DL, HalfCarryVT, Add1_Hi,
2173 Mulhi2_Hi, Add2_Lo.getValue(1));
2174 SDValue Add2 = DAG.getBitcast(VT,
2175 DAG.getBuildVector(MVT::v2i32, DL, {Add2_Lo, Add2_Hi}));
2176
2177 SDValue Mulhi3 = DAG.getNode(ISD::MULHU, DL, VT, LHS, Add2);
2178
2179 SDValue Mul3 = DAG.getNode(ISD::MUL, DL, VT, RHS, Mulhi3);
2180
2181 SDValue Mul3_Lo, Mul3_Hi;
2182 std::tie(Mul3_Lo, Mul3_Hi) = DAG.SplitScalar(Mul3, DL, HalfVT, HalfVT);
2183 SDValue Sub1_Lo = DAG.getNode(ISD::USUBO_CARRY, DL, HalfCarryVT, LHS_Lo,
2184 Mul3_Lo, Zero1);
2185 SDValue Sub1_Hi = DAG.getNode(ISD::USUBO_CARRY, DL, HalfCarryVT, LHS_Hi,
2186 Mul3_Hi, Sub1_Lo.getValue(1));
2187 SDValue Sub1_Mi = DAG.getNode(ISD::SUB, DL, HalfVT, LHS_Hi, Mul3_Hi);
2188 SDValue Sub1 = DAG.getBitcast(VT,
2189 DAG.getBuildVector(MVT::v2i32, DL, {Sub1_Lo, Sub1_Hi}));
2190
2191 SDValue MinusOne = DAG.getConstant(0xffffffffu, DL, HalfVT);
2192 SDValue C1 = DAG.getSelectCC(DL, Sub1_Hi, RHS_Hi, MinusOne, Zero,
2193 ISD::SETUGE);
2194 SDValue C2 = DAG.getSelectCC(DL, Sub1_Lo, RHS_Lo, MinusOne, Zero,
2195 ISD::SETUGE);
2196 SDValue C3 = DAG.getSelectCC(DL, Sub1_Hi, RHS_Hi, C2, C1, ISD::SETEQ);
2197
2198 // TODO: Here and below portions of the code can be enclosed into if/endif.
2199 // Currently control flow is unconditional and we have 4 selects after
2200 // potential endif to substitute PHIs.
2201
2202 // if C3 != 0 ...
2203 SDValue Sub2_Lo = DAG.getNode(ISD::USUBO_CARRY, DL, HalfCarryVT, Sub1_Lo,
2204 RHS_Lo, Zero1);
2205 SDValue Sub2_Mi = DAG.getNode(ISD::USUBO_CARRY, DL, HalfCarryVT, Sub1_Mi,
2206 RHS_Hi, Sub1_Lo.getValue(1));
2207 SDValue Sub2_Hi = DAG.getNode(ISD::USUBO_CARRY, DL, HalfCarryVT, Sub2_Mi,
2208 Zero, Sub2_Lo.getValue(1));
2209 SDValue Sub2 = DAG.getBitcast(VT,
2210 DAG.getBuildVector(MVT::v2i32, DL, {Sub2_Lo, Sub2_Hi}));
2211
2212 SDValue Add3 = DAG.getNode(ISD::ADD, DL, VT, Mulhi3, One64);
2213
2214 SDValue C4 = DAG.getSelectCC(DL, Sub2_Hi, RHS_Hi, MinusOne, Zero,
2215 ISD::SETUGE);
2216 SDValue C5 = DAG.getSelectCC(DL, Sub2_Lo, RHS_Lo, MinusOne, Zero,
2217 ISD::SETUGE);
2218 SDValue C6 = DAG.getSelectCC(DL, Sub2_Hi, RHS_Hi, C5, C4, ISD::SETEQ);
2219
2220 // if (C6 != 0)
2221 SDValue Add4 = DAG.getNode(ISD::ADD, DL, VT, Add3, One64);
2222
2223 SDValue Sub3_Lo = DAG.getNode(ISD::USUBO_CARRY, DL, HalfCarryVT, Sub2_Lo,
2224 RHS_Lo, Zero1);
2225 SDValue Sub3_Mi = DAG.getNode(ISD::USUBO_CARRY, DL, HalfCarryVT, Sub2_Mi,
2226 RHS_Hi, Sub2_Lo.getValue(1));
2227 SDValue Sub3_Hi = DAG.getNode(ISD::USUBO_CARRY, DL, HalfCarryVT, Sub3_Mi,
2228 Zero, Sub3_Lo.getValue(1));
2229 SDValue Sub3 = DAG.getBitcast(VT,
2230 DAG.getBuildVector(MVT::v2i32, DL, {Sub3_Lo, Sub3_Hi}));
2231
2232 // endif C6
2233 // endif C3
2234
2235 SDValue Sel1 = DAG.getSelectCC(DL, C6, Zero, Add4, Add3, ISD::SETNE);
2236 SDValue Div = DAG.getSelectCC(DL, C3, Zero, Sel1, Mulhi3, ISD::SETNE);
2237
2238 SDValue Sel2 = DAG.getSelectCC(DL, C6, Zero, Sub3, Sub2, ISD::SETNE);
2239 SDValue Rem = DAG.getSelectCC(DL, C3, Zero, Sel2, Sub1, ISD::SETNE);
2240
2241 Results.push_back(Div);
2242 Results.push_back(Rem);
2243
2244 return;
2245 }
2246
2247 // r600 expandion.
2248 // Get Speculative values
2249 SDValue DIV_Part = DAG.getNode(ISD::UDIV, DL, HalfVT, LHS_Hi, RHS_Lo);
2250 SDValue REM_Part = DAG.getNode(ISD::UREM, DL, HalfVT, LHS_Hi, RHS_Lo);
2251
2252 SDValue REM_Lo = DAG.getSelectCC(DL, RHS_Hi, Zero, REM_Part, LHS_Hi, ISD::SETEQ);
2253 SDValue REM = DAG.getBuildVector(MVT::v2i32, DL, {REM_Lo, Zero});
2254 REM = DAG.getNode(ISD::BITCAST, DL, MVT::i64, REM);
2255
2256 SDValue DIV_Hi = DAG.getSelectCC(DL, RHS_Hi, Zero, DIV_Part, Zero, ISD::SETEQ);
2257 SDValue DIV_Lo = Zero;
2258
2259 const unsigned halfBitWidth = HalfVT.getSizeInBits();
2260
2261 for (unsigned i = 0; i < halfBitWidth; ++i) {
2262 const unsigned bitPos = halfBitWidth - i - 1;
2263 SDValue POS = DAG.getConstant(bitPos, DL, HalfVT);
2264 // Get value of high bit
2265 SDValue HBit = DAG.getNode(ISD::SRL, DL, HalfVT, LHS_Lo, POS);
2266 HBit = DAG.getNode(ISD::AND, DL, HalfVT, HBit, One);
2267 HBit = DAG.getNode(ISD::ZERO_EXTEND, DL, VT, HBit);
2268
2269 // Shift
2270 REM = DAG.getNode(ISD::SHL, DL, VT, REM, DAG.getConstant(1, DL, VT));
2271 // Add LHS high bit
2272 REM = DAG.getNode(ISD::OR, DL, VT, REM, HBit);
2273
2274 SDValue BIT = DAG.getConstant(1ULL << bitPos, DL, HalfVT);
2275 SDValue realBIT = DAG.getSelectCC(DL, REM, RHS, BIT, Zero, ISD::SETUGE);
2276
2277 DIV_Lo = DAG.getNode(ISD::OR, DL, HalfVT, DIV_Lo, realBIT);
2278
2279 // Update REM
2280 SDValue REM_sub = DAG.getNode(ISD::SUB, DL, VT, REM, RHS);
2281 REM = DAG.getSelectCC(DL, REM, RHS, REM_sub, REM, ISD::SETUGE);
2282 }
2283
2284 SDValue DIV = DAG.getBuildVector(MVT::v2i32, DL, {DIV_Lo, DIV_Hi});
2285 DIV = DAG.getNode(ISD::BITCAST, DL, MVT::i64, DIV);
2286 Results.push_back(DIV);
2287 Results.push_back(REM);
2288}
2289
2291 SelectionDAG &DAG) const {
2292 SDLoc DL(Op);
2293 EVT VT = Op.getValueType();
2294
2295 if (VT == MVT::i64) {
2297 LowerUDIVREM64(Op, DAG, Results);
2298 return DAG.getMergeValues(Results, DL);
2299 }
2300
2301 if (VT == MVT::i32) {
2302 if (SDValue Res = LowerDIVREMToFloat(Op, DAG, false))
2303 return Res;
2304 }
2305
2306 SDValue X = Op.getOperand(0);
2307 SDValue Y = Op.getOperand(1);
2308
2309 // See AMDGPUCodeGenPrepare::expandDivRem32 for a description of the
2310 // algorithm used here.
2311
2312 // Initial estimate of inv(y).
2313 SDValue Z = DAG.getNode(AMDGPUISD::URECIP, DL, VT, Y);
2314
2315 // One round of UNR.
2316 SDValue NegY = DAG.getNode(ISD::SUB, DL, VT, DAG.getConstant(0, DL, VT), Y);
2317 SDValue NegYZ = DAG.getNode(ISD::MUL, DL, VT, NegY, Z);
2318 Z = DAG.getNode(ISD::ADD, DL, VT, Z,
2319 DAG.getNode(ISD::MULHU, DL, VT, Z, NegYZ));
2320
2321 // Quotient/remainder estimate.
2322 SDValue Q = DAG.getNode(ISD::MULHU, DL, VT, X, Z);
2323 SDValue R =
2324 DAG.getNode(ISD::SUB, DL, VT, X, DAG.getNode(ISD::MUL, DL, VT, Q, Y));
2325
2326 // First quotient/remainder refinement.
2327 EVT CCVT = getSetCCResultType(DAG.getDataLayout(), *DAG.getContext(), VT);
2328 SDValue One = DAG.getConstant(1, DL, VT);
2329 SDValue Cond = DAG.getSetCC(DL, CCVT, R, Y, ISD::SETUGE);
2330 Q = DAG.getNode(ISD::SELECT, DL, VT, Cond,
2331 DAG.getNode(ISD::ADD, DL, VT, Q, One), Q);
2332 R = DAG.getNode(ISD::SELECT, DL, VT, Cond,
2333 DAG.getNode(ISD::SUB, DL, VT, R, Y), R);
2334
2335 // Second quotient/remainder refinement.
2336 Cond = DAG.getSetCC(DL, CCVT, R, Y, ISD::SETUGE);
2337 Q = DAG.getNode(ISD::SELECT, DL, VT, Cond,
2338 DAG.getNode(ISD::ADD, DL, VT, Q, One), Q);
2339 R = DAG.getNode(ISD::SELECT, DL, VT, Cond,
2340 DAG.getNode(ISD::SUB, DL, VT, R, Y), R);
2341
2342 return DAG.getMergeValues({Q, R}, DL);
2343}
2344
2346 SelectionDAG &DAG) const {
2347 SDLoc DL(Op);
2348 EVT VT = Op.getValueType();
2349
2350 SDValue LHS = Op.getOperand(0);
2351 SDValue RHS = Op.getOperand(1);
2352
2353 SDValue Zero = DAG.getConstant(0, DL, VT);
2354 SDValue NegOne = DAG.getAllOnesConstant(DL, VT);
2355
2356 if (VT == MVT::i32) {
2357 if (SDValue Res = LowerDIVREMToFloat(Op, DAG, true))
2358 return Res;
2359 }
2360
2361 // LHS must have > 33 sign-bits to ensure that LHS != -2147483648
2362 // Otherwise 32-bit division cannot be used safely.
2363 // -2147483648/1 and -2147483648/-1 are not equal,
2364 // but they produce the same lower 32-bit result.
2365 if (VT == MVT::i64 && DAG.ComputeNumSignBits(LHS) > 33 &&
2366 DAG.ComputeNumSignBits(RHS) > 32) {
2367 EVT HalfVT = VT.getHalfSizedIntegerVT(*DAG.getContext());
2368
2369 //HiLo split
2370 SDValue LHS_Lo = DAG.getNode(ISD::EXTRACT_ELEMENT, DL, HalfVT, LHS, Zero);
2371 SDValue RHS_Lo = DAG.getNode(ISD::EXTRACT_ELEMENT, DL, HalfVT, RHS, Zero);
2372 SDValue DIVREM = DAG.getNode(ISD::SDIVREM, DL, DAG.getVTList(HalfVT, HalfVT),
2373 LHS_Lo, RHS_Lo);
2374 SDValue Res[2] = {
2375 DAG.getNode(ISD::SIGN_EXTEND, DL, VT, DIVREM.getValue(0)),
2376 DAG.getNode(ISD::SIGN_EXTEND, DL, VT, DIVREM.getValue(1))
2377 };
2378 return DAG.getMergeValues(Res, DL);
2379 }
2380
2381 SDValue LHSign = DAG.getSelectCC(DL, LHS, Zero, NegOne, Zero, ISD::SETLT);
2382 SDValue RHSign = DAG.getSelectCC(DL, RHS, Zero, NegOne, Zero, ISD::SETLT);
2383 SDValue DSign = DAG.getNode(ISD::XOR, DL, VT, LHSign, RHSign);
2384 SDValue RSign = LHSign; // Remainder sign is the same as LHS
2385
2386 LHS = DAG.getNode(ISD::ADD, DL, VT, LHS, LHSign);
2387 RHS = DAG.getNode(ISD::ADD, DL, VT, RHS, RHSign);
2388
2389 LHS = DAG.getNode(ISD::XOR, DL, VT, LHS, LHSign);
2390 RHS = DAG.getNode(ISD::XOR, DL, VT, RHS, RHSign);
2391
2392 SDValue Div = DAG.getNode(ISD::UDIVREM, DL, DAG.getVTList(VT, VT), LHS, RHS);
2393 SDValue Rem = Div.getValue(1);
2394
2395 Div = DAG.getNode(ISD::XOR, DL, VT, Div, DSign);
2396 Rem = DAG.getNode(ISD::XOR, DL, VT, Rem, RSign);
2397
2398 Div = DAG.getNode(ISD::SUB, DL, VT, Div, DSign);
2399 Rem = DAG.getNode(ISD::SUB, DL, VT, Rem, RSign);
2400
2401 SDValue Res[2] = {
2402 Div,
2403 Rem
2404 };
2405 return DAG.getMergeValues(Res, DL);
2406}
2407
2409 SDLoc SL(Op);
2410 SDValue Src = Op.getOperand(0);
2411
2412 // result = trunc(src)
2413 // if (src > 0.0 && src != result)
2414 // result += 1.0
2415
2416 SDValue Trunc = DAG.getNode(ISD::FTRUNC, SL, MVT::f64, Src);
2417
2418 const SDValue Zero = DAG.getConstantFP(0.0, SL, MVT::f64);
2419 const SDValue One = DAG.getConstantFP(1.0, SL, MVT::f64);
2420
2421 EVT SetCCVT =
2422 getSetCCResultType(DAG.getDataLayout(), *DAG.getContext(), MVT::f64);
2423
2424 SDValue Lt0 = DAG.getSetCC(SL, SetCCVT, Src, Zero, ISD::SETOGT);
2425 SDValue NeTrunc = DAG.getSetCC(SL, SetCCVT, Src, Trunc, ISD::SETONE);
2426 SDValue And = DAG.getNode(ISD::AND, SL, SetCCVT, Lt0, NeTrunc);
2427
2428 SDValue Add = DAG.getNode(ISD::SELECT, SL, MVT::f64, And, One, Zero);
2429 // TODO: Should this propagate fast-math-flags?
2430 return DAG.getNode(ISD::FADD, SL, MVT::f64, Trunc, Add);
2431}
2432
2434 SelectionDAG &DAG) {
2435 const unsigned FractBits = 52;
2436 const unsigned ExpBits = 11;
2437
2438 SDValue ExpPart = DAG.getNode(AMDGPUISD::BFE_U32, SL, MVT::i32,
2439 Hi,
2440 DAG.getConstant(FractBits - 32, SL, MVT::i32),
2441 DAG.getConstant(ExpBits, SL, MVT::i32));
2442 SDValue Exp = DAG.getNode(ISD::SUB, SL, MVT::i32, ExpPart,
2443 DAG.getConstant(1023, SL, MVT::i32));
2444
2445 return Exp;
2446}
2447
2449 SDLoc SL(Op);
2450 SDValue Src = Op.getOperand(0);
2451
2452 assert(Op.getValueType() == MVT::f64);
2453
2454 const SDValue Zero = DAG.getConstant(0, SL, MVT::i32);
2455
2456 // Extract the upper half, since this is where we will find the sign and
2457 // exponent.
2458 SDValue Hi = getHiHalf64(Src, DAG);
2459
2460 SDValue Exp = extractF64Exponent(Hi, SL, DAG);
2461
2462 const unsigned FractBits = 52;
2463
2464 // Extract the sign bit.
2465 const SDValue SignBitMask = DAG.getConstant(UINT32_C(1) << 31, SL, MVT::i32);
2466 SDValue SignBit = DAG.getNode(ISD::AND, SL, MVT::i32, Hi, SignBitMask);
2467
2468 // Extend back to 64-bits.
2469 SDValue SignBit64 = DAG.getBuildVector(MVT::v2i32, SL, {Zero, SignBit});
2470 SignBit64 = DAG.getNode(ISD::BITCAST, SL, MVT::i64, SignBit64);
2471
2472 SDValue BcInt = DAG.getNode(ISD::BITCAST, SL, MVT::i64, Src);
2473 const SDValue FractMask
2474 = DAG.getConstant((UINT64_C(1) << FractBits) - 1, SL, MVT::i64);
2475
2476 SDValue Shr = DAG.getNode(ISD::SRA, SL, MVT::i64, FractMask, Exp);
2477 SDValue Not = DAG.getNOT(SL, Shr, MVT::i64);
2478 SDValue Tmp0 = DAG.getNode(ISD::AND, SL, MVT::i64, BcInt, Not);
2479
2480 EVT SetCCVT =
2481 getSetCCResultType(DAG.getDataLayout(), *DAG.getContext(), MVT::i32);
2482
2483 const SDValue FiftyOne = DAG.getConstant(FractBits - 1, SL, MVT::i32);
2484
2485 SDValue ExpLt0 = DAG.getSetCC(SL, SetCCVT, Exp, Zero, ISD::SETLT);
2486 SDValue ExpGt51 = DAG.getSetCC(SL, SetCCVT, Exp, FiftyOne, ISD::SETGT);
2487
2488 SDValue Tmp1 = DAG.getNode(ISD::SELECT, SL, MVT::i64, ExpLt0, SignBit64, Tmp0);
2489 SDValue Tmp2 = DAG.getNode(ISD::SELECT, SL, MVT::i64, ExpGt51, BcInt, Tmp1);
2490
2491 return DAG.getNode(ISD::BITCAST, SL, MVT::f64, Tmp2);
2492}
2493
2495 SelectionDAG &DAG) const {
2496 SDLoc SL(Op);
2497 SDValue Src = Op.getOperand(0);
2498
2499 assert(Op.getValueType() == MVT::f64);
2500
2501 APFloat C1Val(APFloat::IEEEdouble(), "0x1.0p+52");
2502 SDValue C1 = DAG.getConstantFP(C1Val, SL, MVT::f64);
2503 SDValue CopySign = DAG.getNode(ISD::FCOPYSIGN, SL, MVT::f64, C1, Src);
2504
2505 // TODO: Should this propagate fast-math-flags?
2506
2507 SDValue Tmp1 = DAG.getNode(ISD::FADD, SL, MVT::f64, Src, CopySign);
2508 SDValue Tmp2 = DAG.getNode(ISD::FSUB, SL, MVT::f64, Tmp1, CopySign);
2509
2510 SDValue Fabs = DAG.getNode(ISD::FABS, SL, MVT::f64, Src);
2511
2512 APFloat C2Val(APFloat::IEEEdouble(), "0x1.fffffffffffffp+51");
2513 SDValue C2 = DAG.getConstantFP(C2Val, SL, MVT::f64);
2514
2515 EVT SetCCVT =
2516 getSetCCResultType(DAG.getDataLayout(), *DAG.getContext(), MVT::f64);
2517 SDValue Cond = DAG.getSetCC(SL, SetCCVT, Fabs, C2, ISD::SETOGT);
2518
2519 return DAG.getSelect(SL, MVT::f64, Cond, Src, Tmp2);
2520}
2521
2523 SelectionDAG &DAG) const {
2524 // FNEARBYINT and FRINT are the same, except in their handling of FP
2525 // exceptions. Those aren't really meaningful for us, and OpenCL only has
2526 // rint, so just treat them as equivalent.
2527 return DAG.getNode(ISD::FROUNDEVEN, SDLoc(Op), Op.getValueType(),
2528 Op.getOperand(0));
2529}
2530
2532 auto VT = Op.getValueType();
2533 auto Arg = Op.getOperand(0u);
2534 return DAG.getNode(ISD::FROUNDEVEN, SDLoc(Op), VT, Arg);
2535}
2536
2537// XXX - May require not supporting f32 denormals?
2538
2539// Don't handle v2f16. The extra instructions to scalarize and repack around the
2540// compare and vselect end up producing worse code than scalarizing the whole
2541// operation.
2543 SDLoc SL(Op);
2544 SDValue X = Op.getOperand(0);
2545 EVT VT = Op.getValueType();
2546
2547 SDValue T = DAG.getNode(ISD::FTRUNC, SL, VT, X);
2548
2549 // TODO: Should this propagate fast-math-flags?
2550
2551 SDValue Diff = DAG.getNode(ISD::FSUB, SL, VT, X, T);
2552
2553 SDValue AbsDiff = DAG.getNode(ISD::FABS, SL, VT, Diff);
2554
2555 const SDValue Zero = DAG.getConstantFP(0.0, SL, VT);
2556 const SDValue One = DAG.getConstantFP(1.0, SL, VT);
2557
2558 EVT SetCCVT =
2559 getSetCCResultType(DAG.getDataLayout(), *DAG.getContext(), VT);
2560
2561 const SDValue Half = DAG.getConstantFP(0.5, SL, VT);
2562 SDValue Cmp = DAG.getSetCC(SL, SetCCVT, AbsDiff, Half, ISD::SETOGE);
2563 SDValue OneOrZeroFP = DAG.getNode(ISD::SELECT, SL, VT, Cmp, One, Zero);
2564
2565 SDValue SignedOffset = DAG.getNode(ISD::FCOPYSIGN, SL, VT, OneOrZeroFP, X);
2566 return DAG.getNode(ISD::FADD, SL, VT, T, SignedOffset);
2567}
2568
2570 SDLoc SL(Op);
2571 SDValue Src = Op.getOperand(0);
2572
2573 // result = trunc(src);
2574 // if (src < 0.0 && src != result)
2575 // result += -1.0.
2576
2577 SDValue Trunc = DAG.getNode(ISD::FTRUNC, SL, MVT::f64, Src);
2578
2579 const SDValue Zero = DAG.getConstantFP(0.0, SL, MVT::f64);
2580 const SDValue NegOne = DAG.getConstantFP(-1.0, SL, MVT::f64);
2581
2582 EVT SetCCVT =
2583 getSetCCResultType(DAG.getDataLayout(), *DAG.getContext(), MVT::f64);
2584
2585 SDValue Lt0 = DAG.getSetCC(SL, SetCCVT, Src, Zero, ISD::SETOLT);
2586 SDValue NeTrunc = DAG.getSetCC(SL, SetCCVT, Src, Trunc, ISD::SETONE);
2587 SDValue And = DAG.getNode(ISD::AND, SL, SetCCVT, Lt0, NeTrunc);
2588
2589 SDValue Add = DAG.getNode(ISD::SELECT, SL, MVT::f64, And, NegOne, Zero);
2590 // TODO: Should this propagate fast-math-flags?
2591 return DAG.getNode(ISD::FADD, SL, MVT::f64, Trunc, Add);
2592}
2593
2594/// Return true if it's known that \p Src can never be an f32 denormal value.
2596 switch (Src.getOpcode()) {
2597 case ISD::FP_EXTEND:
2598 return Src.getOperand(0).getValueType() == MVT::f16;
2599 case ISD::FP16_TO_FP:
2600 case ISD::FFREXP:
2601 case ISD::FSQRT:
2602 case AMDGPUISD::LOG:
2603 case AMDGPUISD::EXP:
2604 return true;
2606 unsigned IntrinsicID = Src.getConstantOperandVal(0);
2607 switch (IntrinsicID) {
2608 case Intrinsic::amdgcn_frexp_mant:
2609 case Intrinsic::amdgcn_log:
2610 case Intrinsic::amdgcn_log_clamp:
2611 case Intrinsic::amdgcn_exp2:
2612 case Intrinsic::amdgcn_sqrt:
2613 return true;
2614 default:
2615 return false;
2616 }
2617 }
2618 default:
2619 return false;
2620 }
2621
2622 llvm_unreachable("covered opcode switch");
2623}
2624
2626 SDNodeFlags Flags) {
2627 return Flags.hasApproximateFuncs();
2628}
2629
2638
2640 SDNodeFlags Flags) const {
2641 SDLoc SL(Src);
2642 EVT VT = Src.getValueType();
2643 const fltSemantics &Semantics = VT.getFltSemantics();
2644 SDValue Inf = DAG.getConstantFP(APFloat::getInf(Semantics), SL, VT);
2645
2646 SDValue Fabs = DAG.getNode(ISD::FABS, SL, VT, Src, Flags);
2647 SDValue IsFinite = DAG.getSetCC(
2648 SL, getSetCCResultType(DAG.getDataLayout(), *DAG.getContext(), VT), Fabs,
2649 Inf, ISD::SETOLT);
2650 return IsFinite;
2651}
2652
2653/// If denormal handling is required return the scaled input to FLOG2, and the
2654/// check for denormal range. Otherwise, return null values.
2655std::pair<SDValue, SDValue>
2657 SDValue Src, SDNodeFlags Flags) const {
2658 if (!needsDenormHandlingF32(DAG, Src, Flags))
2659 return {};
2660
2661 MVT VT = MVT::f32;
2662 const fltSemantics &Semantics = APFloat::IEEEsingle();
2663 SDValue SmallestNormal =
2664 DAG.getConstantFP(APFloat::getSmallestNormalized(Semantics), SL, VT);
2665
2666 SDValue IsLtSmallestNormal = DAG.getSetCC(
2667 SL, getSetCCResultType(DAG.getDataLayout(), *DAG.getContext(), VT), Src,
2668 SmallestNormal, ISD::SETOLT);
2669
2670 SDValue Scale32 = DAG.getConstantFP(0x1.0p+32, SL, VT);
2671 SDValue One = DAG.getConstantFP(1.0, SL, VT);
2672 SDValue ScaleFactor =
2673 DAG.getNode(ISD::SELECT, SL, VT, IsLtSmallestNormal, Scale32, One, Flags);
2674
2675 SDValue ScaledInput = DAG.getNode(ISD::FMUL, SL, VT, Src, ScaleFactor, Flags);
2676 return {ScaledInput, IsLtSmallestNormal};
2677}
2678
2680 // v_log_f32 is good enough for OpenCL, except it doesn't handle denormals.
2681 // If we have to handle denormals, scale up the input and adjust the result.
2682
2683 // scaled = x * (is_denormal ? 0x1.0p+32 : 1.0)
2684 // log2 = amdgpu_log2 - (is_denormal ? 32.0 : 0.0)
2685
2686 SDLoc SL(Op);
2687 EVT VT = Op.getValueType();
2688 SDValue Src = Op.getOperand(0);
2689 SDNodeFlags Flags = Op->getFlags();
2690
2691 if (VT == MVT::f16) {
2692 // Nothing in half is a denormal when promoted to f32.
2693 assert(!isTypeLegal(VT));
2694 SDValue Ext = DAG.getNode(ISD::FP_EXTEND, SL, MVT::f32, Src, Flags);
2695 SDValue Log = DAG.getNode(AMDGPUISD::LOG, SL, MVT::f32, Ext, Flags);
2696 return DAG.getNode(ISD::FP_ROUND, SL, VT, Log,
2697 DAG.getTargetConstant(0, SL, MVT::i32), Flags);
2698 }
2699
2700 auto [ScaledInput, IsLtSmallestNormal] =
2701 getScaledLogInput(DAG, SL, Src, Flags);
2702 if (!ScaledInput)
2703 return DAG.getNode(AMDGPUISD::LOG, SL, VT, Src, Flags);
2704
2705 SDValue Log2 = DAG.getNode(AMDGPUISD::LOG, SL, VT, ScaledInput, Flags);
2706
2707 SDValue ThirtyTwo = DAG.getConstantFP(32.0, SL, VT);
2708 SDValue Zero = DAG.getConstantFP(0.0, SL, VT);
2709 SDValue ResultOffset =
2710 DAG.getNode(ISD::SELECT, SL, VT, IsLtSmallestNormal, ThirtyTwo, Zero);
2711 return DAG.getNode(ISD::FSUB, SL, VT, Log2, ResultOffset, Flags);
2712}
2713
2714static SDValue getMad(SelectionDAG &DAG, const SDLoc &SL, EVT VT, SDValue X,
2715 SDValue Y, SDValue C, SDNodeFlags Flags = SDNodeFlags()) {
2716 SDValue Mul = DAG.getNode(ISD::FMUL, SL, VT, X, Y, Flags);
2717 return DAG.getNode(ISD::FADD, SL, VT, Mul, C, Flags);
2718}
2719
2721 SelectionDAG &DAG) const {
2722 SDValue X = Op.getOperand(0);
2723 EVT VT = Op.getValueType();
2724 SDNodeFlags Flags = Op->getFlags();
2725 SDLoc DL(Op);
2726 const bool IsLog10 = Op.getOpcode() == ISD::FLOG10;
2727 assert(IsLog10 || Op.getOpcode() == ISD::FLOG);
2728
2729 if (VT == MVT::f16 || Flags.hasApproximateFuncs()) {
2730 // TODO: The direct f16 path is 1.79 ulp for f16. This should be used
2731 // depending on !fpmath metadata.
2732
2733 bool PromoteToF32 = VT == MVT::f16 && (!Flags.hasApproximateFuncs() ||
2734 !isTypeLegal(MVT::f16));
2735
2736 if (PromoteToF32) {
2737 // Log and multiply in f32 is always good enough for f16.
2738 X = DAG.getNode(ISD::FP_EXTEND, DL, MVT::f32, X, Flags);
2739 }
2740
2741 SDValue Lowered = LowerFLOGUnsafe(X, DL, DAG, IsLog10, Flags);
2742 if (PromoteToF32) {
2743 return DAG.getNode(ISD::FP_ROUND, DL, VT, Lowered,
2744 DAG.getTargetConstant(0, DL, MVT::i32), Flags);
2745 }
2746
2747 return Lowered;
2748 }
2749
2750 SDValue ScaledInput, IsScaled;
2751 if (VT == MVT::f16)
2752 X = DAG.getNode(ISD::FP_EXTEND, DL, MVT::f32, X, Flags);
2753 else {
2754 std::tie(ScaledInput, IsScaled) = getScaledLogInput(DAG, DL, X, Flags);
2755 if (ScaledInput)
2756 X = ScaledInput;
2757 }
2758
2759 SDValue Y = DAG.getNode(AMDGPUISD::LOG, DL, VT, X, Flags);
2760
2761 SDValue R;
2762 if (Subtarget->hasFastFMAF32()) {
2763 // c+cc are ln(2)/ln(10) to more than 49 bits
2764 const float c_log10 = 0x1.344134p-2f;
2765 const float cc_log10 = 0x1.09f79ep-26f;
2766
2767 // c + cc is ln(2) to more than 49 bits
2768 const float c_log = 0x1.62e42ep-1f;
2769 const float cc_log = 0x1.efa39ep-25f;
2770
2771 SDValue C = DAG.getConstantFP(IsLog10 ? c_log10 : c_log, DL, VT);
2772 SDValue CC = DAG.getConstantFP(IsLog10 ? cc_log10 : cc_log, DL, VT);
2773 // This adds correction terms for which contraction may lead to an increase
2774 // in the error of the approximation, so disable it.
2775 Flags.setAllowContract(false);
2776 R = DAG.getNode(ISD::FMUL, DL, VT, Y, C, Flags);
2777 SDValue NegR = DAG.getNode(ISD::FNEG, DL, VT, R, Flags);
2778 SDValue FMA0 = DAG.getNode(ISD::FMA, DL, VT, Y, C, NegR, Flags);
2779 SDValue FMA1 = DAG.getNode(ISD::FMA, DL, VT, Y, CC, FMA0, Flags);
2780 R = DAG.getNode(ISD::FADD, DL, VT, R, FMA1, Flags);
2781 } else {
2782 // ch+ct is ln(2)/ln(10) to more than 36 bits
2783 const float ch_log10 = 0x1.344000p-2f;
2784 const float ct_log10 = 0x1.3509f6p-18f;
2785
2786 // ch + ct is ln(2) to more than 36 bits
2787 const float ch_log = 0x1.62e000p-1f;
2788 const float ct_log = 0x1.0bfbe8p-15f;
2789
2790 SDValue CH = DAG.getConstantFP(IsLog10 ? ch_log10 : ch_log, DL, VT);
2791 SDValue CT = DAG.getConstantFP(IsLog10 ? ct_log10 : ct_log, DL, VT);
2792
2793 SDValue YAsInt = DAG.getNode(ISD::BITCAST, DL, MVT::i32, Y);
2794 SDValue MaskConst = DAG.getConstant(0xfffff000, DL, MVT::i32);
2795 SDValue YHInt = DAG.getNode(ISD::AND, DL, MVT::i32, YAsInt, MaskConst);
2796 SDValue YH = DAG.getNode(ISD::BITCAST, DL, MVT::f32, YHInt);
2797 SDValue YT = DAG.getNode(ISD::FSUB, DL, VT, Y, YH, Flags);
2798 // This adds correction terms for which contraction may lead to an increase
2799 // in the error of the approximation, so disable it.
2800 Flags.setAllowContract(false);
2801 SDValue YTCT = DAG.getNode(ISD::FMUL, DL, VT, YT, CT, Flags);
2802 SDValue Mad0 = getMad(DAG, DL, VT, YH, CT, YTCT, Flags);
2803 SDValue Mad1 = getMad(DAG, DL, VT, YT, CH, Mad0, Flags);
2804 R = getMad(DAG, DL, VT, YH, CH, Mad1);
2805 }
2806
2807 const bool IsFiniteOnly = Flags.hasNoNaNs() && Flags.hasNoInfs();
2808
2809 // TODO: Check if known finite from source value.
2810 if (!IsFiniteOnly) {
2811 SDValue IsFinite = getIsFinite(DAG, Y, Flags);
2812 R = DAG.getNode(ISD::SELECT, DL, VT, IsFinite, R, Y, Flags);
2813 }
2814
2815 if (IsScaled) {
2816 SDValue Zero = DAG.getConstantFP(0.0f, DL, VT);
2817 SDValue ShiftK =
2818 DAG.getConstantFP(IsLog10 ? 0x1.344136p+3f : 0x1.62e430p+4f, DL, VT);
2819 SDValue Shift =
2820 DAG.getNode(ISD::SELECT, DL, VT, IsScaled, ShiftK, Zero, Flags);
2821 R = DAG.getNode(ISD::FSUB, DL, VT, R, Shift, Flags);
2822 }
2823
2824 return R;
2825}
2826
2827// Do f32 fast math expansion for flog2 or flog10. This is accurate enough for a
2828// promote f16 operation.
2830 SelectionDAG &DAG, bool IsLog10,
2831 SDNodeFlags Flags) const {
2832 EVT VT = Src.getValueType();
2833 unsigned LogOp =
2834 VT == MVT::f32 ? (unsigned)AMDGPUISD::LOG : (unsigned)ISD::FLOG2;
2835
2836 double Log2BaseInverted =
2838
2839 if (VT == MVT::f32) {
2840 auto [ScaledInput, IsScaled] = getScaledLogInput(DAG, SL, Src, Flags);
2841 if (ScaledInput) {
2842 SDValue LogSrc = DAG.getNode(AMDGPUISD::LOG, SL, VT, ScaledInput, Flags);
2843 SDValue ScaledResultOffset =
2844 DAG.getConstantFP(-32.0 * Log2BaseInverted, SL, VT);
2845
2846 SDValue Zero = DAG.getConstantFP(0.0f, SL, VT);
2847
2848 SDValue ResultOffset = DAG.getNode(ISD::SELECT, SL, VT, IsScaled,
2849 ScaledResultOffset, Zero, Flags);
2850
2851 SDValue Log2Inv = DAG.getConstantFP(Log2BaseInverted, SL, VT);
2852
2853 if (Subtarget->hasFastFMAF32())
2854 return DAG.getNode(ISD::FMA, SL, VT, LogSrc, Log2Inv, ResultOffset,
2855 Flags);
2856 SDValue Mul = DAG.getNode(ISD::FMUL, SL, VT, LogSrc, Log2Inv, Flags);
2857 return DAG.getNode(ISD::FADD, SL, VT, Mul, ResultOffset);
2858 }
2859 }
2860
2861 SDValue Log2Operand = DAG.getNode(LogOp, SL, VT, Src, Flags);
2862 SDValue Log2BaseInvertedOperand = DAG.getConstantFP(Log2BaseInverted, SL, VT);
2863
2864 return DAG.getNode(ISD::FMUL, SL, VT, Log2Operand, Log2BaseInvertedOperand,
2865 Flags);
2866}
2867
2868// This expansion gives a result slightly better than 1ulp.
2870 SelectionDAG &DAG) const {
2871 SDLoc DL(Op);
2872 SDValue X = Op.getOperand(0);
2873
2874 // TODO: Check if reassoc is safe. There is an output change in exp2 and
2875 // exp10, which slightly increases ulp.
2876 SDNodeFlags Flags = Op->getFlags() & ~SDNodeFlags::AllowReassociation;
2877
2878 SDValue DN, F, T;
2879
2880 if (Op.getOpcode() == ISD::FEXP2) {
2881 // dn = rint(x)
2882 DN = DAG.getNode(ISD::FRINT, DL, MVT::f64, X, Flags);
2883 // f = x - dn
2884 F = DAG.getNode(ISD::FSUB, DL, MVT::f64, X, DN, Flags);
2885 // t = f*C1 + f*C2
2886 SDValue C1 = DAG.getConstantFP(0x1.62e42fefa39efp-1, DL, MVT::f64);
2887 SDValue C2 = DAG.getConstantFP(0x1.abc9e3b39803fp-56, DL, MVT::f64);
2888 SDValue Mul2 = DAG.getNode(ISD::FMUL, DL, MVT::f64, F, C2, Flags);
2889 T = DAG.getNode(ISD::FMA, DL, MVT::f64, F, C1, Mul2, Flags);
2890 } else if (Op.getOpcode() == ISD::FEXP10) {
2891 // dn = rint(x * C1)
2892 SDValue C1 = DAG.getConstantFP(0x1.a934f0979a371p+1, DL, MVT::f64);
2893 SDValue Mul = DAG.getNode(ISD::FMUL, DL, MVT::f64, X, C1, Flags);
2894 DN = DAG.getNode(ISD::FRINT, DL, MVT::f64, Mul, Flags);
2895
2896 // f = FMA(-dn, C2, FMA(-dn, C3, x))
2897 SDValue NegDN = DAG.getNode(ISD::FNEG, DL, MVT::f64, DN, Flags);
2898 SDValue C2 = DAG.getConstantFP(-0x1.9dc1da994fd21p-59, DL, MVT::f64);
2899 SDValue C3 = DAG.getConstantFP(0x1.34413509f79ffp-2, DL, MVT::f64);
2900 SDValue Inner = DAG.getNode(ISD::FMA, DL, MVT::f64, NegDN, C3, X, Flags);
2901 F = DAG.getNode(ISD::FMA, DL, MVT::f64, NegDN, C2, Inner, Flags);
2902
2903 // t = FMA(f, C4, f*C5)
2904 SDValue C4 = DAG.getConstantFP(0x1.26bb1bbb55516p+1, DL, MVT::f64);
2905 SDValue C5 = DAG.getConstantFP(-0x1.f48ad494ea3e9p-53, DL, MVT::f64);
2906 SDValue MulF = DAG.getNode(ISD::FMUL, DL, MVT::f64, F, C5, Flags);
2907 T = DAG.getNode(ISD::FMA, DL, MVT::f64, F, C4, MulF, Flags);
2908 } else { // ISD::FEXP
2909 // dn = rint(x * C1)
2910 SDValue C1 = DAG.getConstantFP(0x1.71547652b82fep+0, DL, MVT::f64);
2911 SDValue Mul = DAG.getNode(ISD::FMUL, DL, MVT::f64, X, C1, Flags);
2912 DN = DAG.getNode(ISD::FRINT, DL, MVT::f64, Mul, Flags);
2913
2914 // t = FMA(-dn, C2, FMA(-dn, C3, x))
2915 SDValue NegDN = DAG.getNode(ISD::FNEG, DL, MVT::f64, DN, Flags);
2916 SDValue C2 = DAG.getConstantFP(0x1.abc9e3b39803fp-56, DL, MVT::f64);
2917 SDValue C3 = DAG.getConstantFP(0x1.62e42fefa39efp-1, DL, MVT::f64);
2918 SDValue Inner = DAG.getNode(ISD::FMA, DL, MVT::f64, NegDN, C3, X, Flags);
2919 T = DAG.getNode(ISD::FMA, DL, MVT::f64, NegDN, C2, Inner, Flags);
2920 }
2921
2922 // Polynomial expansion for p
2923 SDValue P = DAG.getConstantFP(0x1.ade156a5dcb37p-26, DL, MVT::f64);
2924 P = DAG.getNode(ISD::FMA, DL, MVT::f64, T, P,
2925 DAG.getConstantFP(0x1.28af3fca7ab0cp-22, DL, MVT::f64),
2926 Flags);
2927 P = DAG.getNode(ISD::FMA, DL, MVT::f64, T, P,
2928 DAG.getConstantFP(0x1.71dee623fde64p-19, DL, MVT::f64),
2929 Flags);
2930 P = DAG.getNode(ISD::FMA, DL, MVT::f64, T, P,
2931 DAG.getConstantFP(0x1.a01997c89e6b0p-16, DL, MVT::f64),
2932 Flags);
2933 P = DAG.getNode(ISD::FMA, DL, MVT::f64, T, P,
2934 DAG.getConstantFP(0x1.a01a014761f6ep-13, DL, MVT::f64),
2935 Flags);
2936 P = DAG.getNode(ISD::FMA, DL, MVT::f64, T, P,
2937 DAG.getConstantFP(0x1.6c16c1852b7b0p-10, DL, MVT::f64),
2938 Flags);
2939 P = DAG.getNode(ISD::FMA, DL, MVT::f64, T, P,
2940 DAG.getConstantFP(0x1.1111111122322p-7, DL, MVT::f64), Flags);
2941 P = DAG.getNode(ISD::FMA, DL, MVT::f64, T, P,
2942 DAG.getConstantFP(0x1.55555555502a1p-5, DL, MVT::f64), Flags);
2943 P = DAG.getNode(ISD::FMA, DL, MVT::f64, T, P,
2944 DAG.getConstantFP(0x1.5555555555511p-3, DL, MVT::f64), Flags);
2945 P = DAG.getNode(ISD::FMA, DL, MVT::f64, T, P,
2946 DAG.getConstantFP(0x1.000000000000bp-1, DL, MVT::f64), Flags);
2947
2948 SDValue One = DAG.getConstantFP(1.0, DL, MVT::f64);
2949
2950 P = DAG.getNode(ISD::FMA, DL, MVT::f64, T, P, One, Flags);
2951 P = DAG.getNode(ISD::FMA, DL, MVT::f64, T, P, One, Flags);
2952
2953 // z = ldexp(p, (int)dn)
2954 SDValue DNInt = DAG.getNode(ISD::FP_TO_SINT, DL, MVT::i32, DN);
2955 SDValue Z = DAG.getNode(ISD::FLDEXP, DL, MVT::f64, P, DNInt, Flags);
2956
2957 // Overflow/underflow guards
2958 SDValue CondHi = DAG.getSetCC(
2959 DL, MVT::i1, X, DAG.getConstantFP(1024.0, DL, MVT::f64), ISD::SETULE);
2960
2961 if (!Flags.hasNoInfs()) {
2962 SDValue PInf = DAG.getConstantFP(std::numeric_limits<double>::infinity(),
2963 DL, MVT::f64);
2964 Z = DAG.getSelect(DL, MVT::f64, CondHi, Z, PInf, Flags);
2965 }
2966
2967 SDValue CondLo = DAG.getSetCC(
2968 DL, MVT::i1, X, DAG.getConstantFP(-1075.0, DL, MVT::f64), ISD::SETUGE);
2969 SDValue Zero = DAG.getConstantFP(0.0, DL, MVT::f64);
2970 Z = DAG.getSelect(DL, MVT::f64, CondLo, Z, Zero, Flags);
2971
2972 return Z;
2973}
2974
2976 // v_exp_f32 is good enough for OpenCL, except it doesn't handle denormals.
2977 // If we have to handle denormals, scale up the input and adjust the result.
2978
2979 EVT VT = Op.getValueType();
2980 if (VT == MVT::f64)
2981 return lowerFEXPF64(Op, DAG);
2982
2983 SDLoc SL(Op);
2984 SDValue Src = Op.getOperand(0);
2985 SDNodeFlags Flags = Op->getFlags();
2986
2987 if (VT == MVT::f16) {
2988 // Nothing in half is a denormal when promoted to f32.
2989 assert(!isTypeLegal(MVT::f16));
2990 SDValue Ext = DAG.getNode(ISD::FP_EXTEND, SL, MVT::f32, Src, Flags);
2991 SDValue Log = DAG.getNode(AMDGPUISD::EXP, SL, MVT::f32, Ext, Flags);
2992 return DAG.getNode(ISD::FP_ROUND, SL, VT, Log,
2993 DAG.getTargetConstant(0, SL, MVT::i32), Flags);
2994 }
2995
2996 assert(VT == MVT::f32);
2997
2998 if (!needsDenormHandlingF32(DAG, Src, Flags))
2999 return DAG.getNode(AMDGPUISD::EXP, SL, MVT::f32, Src, Flags);
3000
3001 // bool needs_scaling = x < -0x1.f80000p+6f;
3002 // v_exp_f32(x + (s ? 0x1.0p+6f : 0.0f)) * (s ? 0x1.0p-64f : 1.0f);
3003
3004 // -nextafter(128.0, -1)
3005 SDValue RangeCheckConst = DAG.getConstantFP(-0x1.f80000p+6f, SL, VT);
3006
3007 EVT SetCCVT = getSetCCResultType(DAG.getDataLayout(), *DAG.getContext(), VT);
3008
3009 SDValue NeedsScaling =
3010 DAG.getSetCC(SL, SetCCVT, Src, RangeCheckConst, ISD::SETOLT);
3011
3012 SDValue SixtyFour = DAG.getConstantFP(0x1.0p+6f, SL, VT);
3013 SDValue Zero = DAG.getConstantFP(0.0, SL, VT);
3014
3015 SDValue AddOffset =
3016 DAG.getNode(ISD::SELECT, SL, VT, NeedsScaling, SixtyFour, Zero);
3017
3018 SDValue AddInput = DAG.getNode(ISD::FADD, SL, VT, Src, AddOffset, Flags);
3019 SDValue Exp2 = DAG.getNode(AMDGPUISD::EXP, SL, VT, AddInput, Flags);
3020
3021 SDValue TwoExpNeg64 = DAG.getConstantFP(0x1.0p-64f, SL, VT);
3022 SDValue One = DAG.getConstantFP(1.0, SL, VT);
3023 SDValue ResultScale =
3024 DAG.getNode(ISD::SELECT, SL, VT, NeedsScaling, TwoExpNeg64, One);
3025
3026 return DAG.getNode(ISD::FMUL, SL, VT, Exp2, ResultScale, Flags);
3027}
3028
3030 SelectionDAG &DAG,
3031 SDNodeFlags Flags,
3032 bool IsExp10) const {
3033 // exp(x) -> exp2(M_LOG2E_F * x);
3034 // exp10(x) -> exp2(log2(10) * x);
3035 EVT VT = X.getValueType();
3036 SDValue Const =
3037 DAG.getConstantFP(IsExp10 ? 0x1.a934f0p+1f : numbers::log2e, SL, VT);
3038
3039 SDValue Mul = DAG.getNode(ISD::FMUL, SL, VT, X, Const, Flags);
3040 return DAG.getNode(VT == MVT::f32 ? (unsigned)AMDGPUISD::EXP
3041 : (unsigned)ISD::FEXP2,
3042 SL, VT, Mul, Flags);
3043}
3044
3046 SelectionDAG &DAG,
3047 SDNodeFlags Flags) const {
3048 EVT VT = X.getValueType();
3049 if (VT != MVT::f32 || !needsDenormHandlingF32(DAG, X, Flags))
3050 return lowerFEXPUnsafeImpl(X, SL, DAG, Flags, /*IsExp10=*/false);
3051
3052 EVT SetCCVT = getSetCCResultType(DAG.getDataLayout(), *DAG.getContext(), VT);
3053
3054 SDValue Threshold = DAG.getConstantFP(-0x1.5d58a0p+6f, SL, VT);
3055 SDValue NeedsScaling = DAG.getSetCC(SL, SetCCVT, X, Threshold, ISD::SETOLT);
3056
3057 SDValue ScaleOffset = DAG.getConstantFP(0x1.0p+6f, SL, VT);
3058
3059 SDValue ScaledX = DAG.getNode(ISD::FADD, SL, VT, X, ScaleOffset, Flags);
3060
3061 SDValue AdjustedX =
3062 DAG.getNode(ISD::SELECT, SL, VT, NeedsScaling, ScaledX, X);
3063
3064 const SDValue Log2E = DAG.getConstantFP(numbers::log2e, SL, VT);
3065 SDValue ExpInput = DAG.getNode(ISD::FMUL, SL, VT, AdjustedX, Log2E, Flags);
3066
3067 SDValue Exp2 = DAG.getNode(AMDGPUISD::EXP, SL, VT, ExpInput, Flags);
3068
3069 SDValue ResultScaleFactor = DAG.getConstantFP(0x1.969d48p-93f, SL, VT);
3070 SDValue AdjustedResult =
3071 DAG.getNode(ISD::FMUL, SL, VT, Exp2, ResultScaleFactor, Flags);
3072
3073 return DAG.getNode(ISD::SELECT, SL, VT, NeedsScaling, AdjustedResult, Exp2,
3074 Flags);
3075}
3076
3077/// Emit approx-funcs appropriate lowering for exp10. inf/nan should still be
3078/// handled correctly.
3080 SelectionDAG &DAG,
3081 SDNodeFlags Flags) const {
3082 const EVT VT = X.getValueType();
3083
3084 const unsigned Exp2Op = VT == MVT::f32 ? static_cast<unsigned>(AMDGPUISD::EXP)
3085 : static_cast<unsigned>(ISD::FEXP2);
3086
3087 if (VT != MVT::f32 || !needsDenormHandlingF32(DAG, X, Flags)) {
3088 // exp2(x * 0x1.a92000p+1f) * exp2(x * 0x1.4f0978p-11f);
3089 SDValue K0 = DAG.getConstantFP(0x1.a92000p+1f, SL, VT);
3090 SDValue K1 = DAG.getConstantFP(0x1.4f0978p-11f, SL, VT);
3091
3092 SDValue Mul0 = DAG.getNode(ISD::FMUL, SL, VT, X, K0, Flags);
3093 SDValue Exp2_0 = DAG.getNode(Exp2Op, SL, VT, Mul0, Flags);
3094 SDValue Mul1 = DAG.getNode(ISD::FMUL, SL, VT, X, K1, Flags);
3095 SDValue Exp2_1 = DAG.getNode(Exp2Op, SL, VT, Mul1, Flags);
3096 return DAG.getNode(ISD::FMUL, SL, VT, Exp2_0, Exp2_1);
3097 }
3098
3099 // bool s = x < -0x1.2f7030p+5f;
3100 // x += s ? 0x1.0p+5f : 0.0f;
3101 // exp10 = exp2(x * 0x1.a92000p+1f) *
3102 // exp2(x * 0x1.4f0978p-11f) *
3103 // (s ? 0x1.9f623ep-107f : 1.0f);
3104
3105 EVT SetCCVT = getSetCCResultType(DAG.getDataLayout(), *DAG.getContext(), VT);
3106
3107 SDValue Threshold = DAG.getConstantFP(-0x1.2f7030p+5f, SL, VT);
3108 SDValue NeedsScaling = DAG.getSetCC(SL, SetCCVT, X, Threshold, ISD::SETOLT);
3109
3110 SDValue ScaleOffset = DAG.getConstantFP(0x1.0p+5f, SL, VT);
3111 SDValue ScaledX = DAG.getNode(ISD::FADD, SL, VT, X, ScaleOffset, Flags);
3112 SDValue AdjustedX =
3113 DAG.getNode(ISD::SELECT, SL, VT, NeedsScaling, ScaledX, X);
3114
3115 SDValue K0 = DAG.getConstantFP(0x1.a92000p+1f, SL, VT);
3116 SDValue K1 = DAG.getConstantFP(0x1.4f0978p-11f, SL, VT);
3117
3118 SDValue Mul0 = DAG.getNode(ISD::FMUL, SL, VT, AdjustedX, K0, Flags);
3119 SDValue Exp2_0 = DAG.getNode(Exp2Op, SL, VT, Mul0, Flags);
3120 SDValue Mul1 = DAG.getNode(ISD::FMUL, SL, VT, AdjustedX, K1, Flags);
3121 SDValue Exp2_1 = DAG.getNode(Exp2Op, SL, VT, Mul1, Flags);
3122
3123 SDValue MulExps = DAG.getNode(ISD::FMUL, SL, VT, Exp2_0, Exp2_1, Flags);
3124
3125 SDValue ResultScaleFactor = DAG.getConstantFP(0x1.9f623ep-107f, SL, VT);
3126 SDValue AdjustedResult =
3127 DAG.getNode(ISD::FMUL, SL, VT, MulExps, ResultScaleFactor, Flags);
3128
3129 return DAG.getNode(ISD::SELECT, SL, VT, NeedsScaling, AdjustedResult, MulExps,
3130 Flags);
3131}
3132
3134 EVT VT = Op.getValueType();
3135
3136 if (VT == MVT::f64)
3137 return lowerFEXPF64(Op, DAG);
3138
3139 SDLoc SL(Op);
3140 SDValue X = Op.getOperand(0);
3141 SDNodeFlags Flags = Op->getFlags();
3142 const bool IsExp10 = Op.getOpcode() == ISD::FEXP10;
3143
3144 // TODO: Interpret allowApproxFunc as ignoring DAZ. This is currently copying
3145 // library behavior. Also, is known-not-daz source sufficient?
3146 if (allowApproxFunc(DAG, Flags)) { // TODO: Does this really require fast?
3147 return IsExp10 ? lowerFEXP10Unsafe(X, SL, DAG, Flags)
3148 : lowerFEXPUnsafe(X, SL, DAG, Flags);
3149 }
3150
3151 if (VT.getScalarType() == MVT::f16) {
3152 if (VT.isVector())
3153 return SDValue();
3154
3155 // Nothing in half is a denormal when promoted to f32.
3156 //
3157 // exp(f16 x) ->
3158 // fptrunc (v_exp_f32 (fmul (fpext x), log2e))
3159 //
3160 // exp10(f16 x) ->
3161 // fptrunc (v_exp_f32 (fmul (fpext x), log2(10)))
3162 SDValue Ext = DAG.getNode(ISD::FP_EXTEND, SL, MVT::f32, X, Flags);
3163 SDValue Lowered = lowerFEXPUnsafeImpl(Ext, SL, DAG, Flags, IsExp10);
3164 return DAG.getNode(ISD::FP_ROUND, SL, VT, Lowered,
3165 DAG.getTargetConstant(0, SL, MVT::i32), Flags);
3166 }
3167
3168 assert(VT == MVT::f32);
3169
3170 // Algorithm:
3171 //
3172 // e^x = 2^(x/ln(2)) = 2^(x*(64/ln(2))/64)
3173 //
3174 // x*(64/ln(2)) = n + f, |f| <= 0.5, n is integer
3175 // n = 64*m + j, 0 <= j < 64
3176 //
3177 // e^x = 2^((64*m + j + f)/64)
3178 // = (2^m) * (2^(j/64)) * 2^(f/64)
3179 // = (2^m) * (2^(j/64)) * e^(f*(ln(2)/64))
3180 //
3181 // f = x*(64/ln(2)) - n
3182 // r = f*(ln(2)/64) = x - n*(ln(2)/64)
3183 //
3184 // e^x = (2^m) * (2^(j/64)) * e^r
3185 //
3186 // (2^(j/64)) is precomputed
3187 //
3188 // e^r = 1 + r + (r^2)/2! + (r^3)/3! + (r^4)/4! + (r^5)/5!
3189 // e^r = 1 + q
3190 //
3191 // q = r + (r^2)/2! + (r^3)/3! + (r^4)/4! + (r^5)/5!
3192 //
3193 // e^x = (2^m) * ( (2^(j/64)) + q*(2^(j/64)) )
3194 SDNodeFlags FlagsNoContract = Flags;
3195 FlagsNoContract.setAllowContract(false);
3196
3197 SDValue PH, PL;
3198 if (Subtarget->hasFastFMAF32()) {
3199 const float c_exp = numbers::log2ef;
3200 const float cc_exp = 0x1.4ae0bep-26f; // c+cc are 49 bits
3201 const float c_exp10 = 0x1.a934f0p+1f;
3202 const float cc_exp10 = 0x1.2f346ep-24f;
3203
3204 SDValue C = DAG.getConstantFP(IsExp10 ? c_exp10 : c_exp, SL, VT);
3205 SDValue CC = DAG.getConstantFP(IsExp10 ? cc_exp10 : cc_exp, SL, VT);
3206
3207 PH = DAG.getNode(ISD::FMUL, SL, VT, X, C, Flags);
3208 SDValue NegPH = DAG.getNode(ISD::FNEG, SL, VT, PH, Flags);
3209 SDValue FMA0 = DAG.getNode(ISD::FMA, SL, VT, X, C, NegPH, Flags);
3210 PL = DAG.getNode(ISD::FMA, SL, VT, X, CC, FMA0, Flags);
3211 } else {
3212 const float ch_exp = 0x1.714000p+0f;
3213 const float cl_exp = 0x1.47652ap-12f; // ch + cl are 36 bits
3214
3215 const float ch_exp10 = 0x1.a92000p+1f;
3216 const float cl_exp10 = 0x1.4f0978p-11f;
3217
3218 SDValue CH = DAG.getConstantFP(IsExp10 ? ch_exp10 : ch_exp, SL, VT);
3219 SDValue CL = DAG.getConstantFP(IsExp10 ? cl_exp10 : cl_exp, SL, VT);
3220
3221 SDValue XAsInt = DAG.getNode(ISD::BITCAST, SL, MVT::i32, X);
3222 SDValue MaskConst = DAG.getConstant(0xfffff000, SL, MVT::i32);
3223 SDValue XHAsInt = DAG.getNode(ISD::AND, SL, MVT::i32, XAsInt, MaskConst);
3224 SDValue XH = DAG.getNode(ISD::BITCAST, SL, VT, XHAsInt);
3225 SDValue XL = DAG.getNode(ISD::FSUB, SL, VT, X, XH, Flags);
3226
3227 PH = DAG.getNode(ISD::FMUL, SL, VT, XH, CH, Flags);
3228
3229 SDValue XLCL = DAG.getNode(ISD::FMUL, SL, VT, XL, CL, Flags);
3230 SDValue Mad0 = getMad(DAG, SL, VT, XL, CH, XLCL, Flags);
3231 PL = getMad(DAG, SL, VT, XH, CL, Mad0, Flags);
3232 }
3233
3234 SDValue E = DAG.getNode(ISD::FROUNDEVEN, SL, VT, PH, Flags);
3235
3236 // It is unsafe to contract this fsub into the PH multiply.
3237 SDValue PHSubE = DAG.getNode(ISD::FSUB, SL, VT, PH, E, FlagsNoContract);
3238
3239 SDValue A = DAG.getNode(ISD::FADD, SL, VT, PHSubE, PL, Flags);
3240 SDValue IntE = DAG.getNode(ISD::FP_TO_SINT, SL, MVT::i32, E);
3241 SDValue Exp2 = DAG.getNode(AMDGPUISD::EXP, SL, VT, A, Flags);
3242
3243 SDValue R = DAG.getNode(ISD::FLDEXP, SL, VT, Exp2, IntE, Flags);
3244
3245 SDValue UnderflowCheckConst =
3246 DAG.getConstantFP(IsExp10 ? -0x1.66d3e8p+5f : -0x1.9d1da0p+6f, SL, VT);
3247
3248 EVT SetCCVT = getSetCCResultType(DAG.getDataLayout(), *DAG.getContext(), VT);
3249 SDValue Zero = DAG.getConstantFP(0.0, SL, VT);
3250 SDValue Underflow =
3251 DAG.getSetCC(SL, SetCCVT, X, UnderflowCheckConst, ISD::SETOLT);
3252
3253 R = DAG.getNode(ISD::SELECT, SL, VT, Underflow, Zero, R);
3254
3255 if (!Flags.hasNoInfs()) {
3256 SDValue OverflowCheckConst =
3257 DAG.getConstantFP(IsExp10 ? 0x1.344136p+5f : 0x1.62e430p+6f, SL, VT);
3258 SDValue Overflow =
3259 DAG.getSetCC(SL, SetCCVT, X, OverflowCheckConst, ISD::SETOGT);
3260 SDValue Inf =
3262 R = DAG.getNode(ISD::SELECT, SL, VT, Overflow, Inf, R);
3263 }
3264
3265 return R;
3266}
3267
3268// No pow instruction or libcall to fall back on. fmul_legacy returns 0 for a
3269// zero operand even against an infinity or a NaN, so pow(x, 0) and pow(1, y)
3270// fall out as exp2(0) = 1.
3272 EVT VT = Op.getValueType();
3273 assert(VT == MVT::f32);
3274
3275 SDLoc SL(Op);
3276 SDValue X = Op.getOperand(0);
3277 SDValue Y = Op.getOperand(1);
3278 SDNodeFlags Flags = Op->getFlags();
3279
3280 // log2(0) is -inf, which exp2 turns back into a finite result, so the core
3281 // goes infinite for inputs a ninf fpow still asserts about, like pow(0, 2).
3282 SDNodeFlags CoreFlags = Flags;
3283 CoreFlags.setNoInfs(false);
3284
3285 // Fast expansion: ignores denormals, NaN for a negative base.
3286 if (allowApproxFunc(DAG, Flags)) {
3287 SDValue Log = DAG.getNode(AMDGPUISD::LOG, SL, VT, X, CoreFlags);
3288 SDValue Mul =
3289 DAG.getNode(AMDGPUISD::FMUL_LEGACY, SL, VT, Y, Log, CoreFlags);
3290 return DAG.getNode(AMDGPUISD::EXP, SL, VT, Mul, CoreFlags);
3291 }
3292
3293 SDValue Abs = DAG.getNode(ISD::FABS, SL, VT, X, Flags);
3294 SDValue Log = DAG.getNode(ISD::FLOG2, SL, VT, Abs, CoreFlags);
3295 SDValue Mul = DAG.getNode(AMDGPUISD::FMUL_LEGACY, SL, VT, Y, Log, CoreFlags);
3296 SDValue R = DAG.getNode(ISD::FEXP2, SL, VT, Mul, CoreFlags);
3297
3298 // A base that is never negative needs neither the sign fixup nor the NaN.
3300 return R;
3301
3302 EVT SetCCVT = getSetCCResultType(DAG.getDataLayout(), *DAG.getContext(), VT);
3303
3304 // Infinities count as integers, and every f32 >= 2^24 in magnitude is even.
3305 SDValue YTrunc = DAG.getNode(ISD::FTRUNC, SL, VT, Y);
3306 SDValue YIsInt = DAG.getSetCC(SL, SetCCVT, YTrunc, Y, ISD::SETOEQ);
3307 SDValue YHalf =
3308 DAG.getNode(ISD::FMUL, SL, VT, Y, DAG.getConstantFP(0.5, SL, VT));
3309 SDValue YHalfTrunc = DAG.getNode(ISD::FTRUNC, SL, VT, YHalf);
3310 SDValue YIsOdd =
3311 DAG.getNode(ISD::AND, SL, SetCCVT, YIsInt,
3312 DAG.getSetCC(SL, SetCCVT, YHalfTrunc, YHalf, ISD::SETONE));
3313
3314 // pow(-x, odd y) = -pow(x, y). Selecting the copysign lets even y fold it.
3315 R = DAG.getNode(ISD::SELECT, SL, VT, YIsOdd,
3316 DAG.getNode(ISD::FCOPYSIGN, SL, VT, R, X), R);
3317
3318 if (Flags.hasNoNaNs())
3319 return R;
3320
3321 // A negative finite base to a non-integral power is NaN. -inf is excluded:
3322 // the core already gives pow(+inf, y). So are subnormals when flushed.
3323 FPClassTest NegFiniteMask = fcNegNormal;
3324 if (!DAG.getMachineFunction()
3326 .inputsAreZero())
3327 NegFiniteMask |= fcNegSubnormal;
3328 SDValue XNegFinite =
3329 DAG.getNode(ISD::IS_FPCLASS, SL, SetCCVT, X,
3330 DAG.getTargetConstant(NegFiniteMask, SL, MVT::i32));
3331 // Not a SETONE compare: pow(-1, NaN) needs the NaN-true behavior of !SETOEQ.
3332 SDValue NegNonInt = DAG.getNode(ISD::AND, SL, SetCCVT, XNegFinite,
3333 DAG.getNOT(SL, YIsInt, SetCCVT));
3334 SDValue NaN =
3336 return DAG.getNode(ISD::SELECT, SL, VT, NegNonInt, NaN, R);
3337}
3338
3339static bool isCtlzOpc(unsigned Opc) {
3340 return Opc == ISD::CTLZ || Opc == ISD::CTLZ_ZERO_POISON;
3341}
3342
3343static bool isCttzOpc(unsigned Opc) {
3344 return Opc == ISD::CTTZ || Opc == ISD::CTTZ_ZERO_POISON;
3345}
3346
3348 SelectionDAG &DAG) const {
3349 auto SL = SDLoc(Op);
3350 auto Opc = Op.getOpcode();
3351 auto Arg = Op.getOperand(0u);
3352 auto ResultVT = Op.getValueType();
3353
3354 if (ResultVT != MVT::i8 && ResultVT != MVT::i16)
3355 return {};
3356
3358 assert(ResultVT == Arg.getValueType());
3359
3360 const uint64_t NumBits = ResultVT.getFixedSizeInBits();
3361 SDValue NumExtBits = DAG.getConstant(32u - NumBits, SL, MVT::i32);
3362 SDValue NewOp;
3363
3364 if (Opc == ISD::CTLZ_ZERO_POISON) {
3365 NewOp = DAG.getNode(ISD::ANY_EXTEND, SL, MVT::i32, Arg);
3366 NewOp = DAG.getNode(ISD::SHL, SL, MVT::i32, NewOp, NumExtBits);
3367 NewOp = DAG.getNode(Opc, SL, MVT::i32, NewOp);
3368 } else {
3369 NewOp = DAG.getNode(ISD::ZERO_EXTEND, SL, MVT::i32, Arg);
3370 NewOp = DAG.getNode(Opc, SL, MVT::i32, NewOp);
3371 NewOp = DAG.getNode(ISD::SUB, SL, MVT::i32, NewOp, NumExtBits);
3372 }
3373
3374 return DAG.getNode(ISD::TRUNCATE, SL, ResultVT, NewOp);
3375}
3376
3378 SDLoc SL(Op);
3379 SDValue Src = Op.getOperand(0);
3380
3381 assert(isCtlzOpc(Op.getOpcode()) || isCttzOpc(Op.getOpcode()));
3382 bool Ctlz = isCtlzOpc(Op.getOpcode());
3383 unsigned NewOpc = Ctlz ? AMDGPUISD::FFBH_U32 : AMDGPUISD::FFBL_B32;
3384
3385 bool ZeroUndef = Op.getOpcode() == ISD::CTLZ_ZERO_POISON ||
3386 Op.getOpcode() == ISD::CTTZ_ZERO_POISON;
3387 bool Is64BitScalar = !Src->isDivergent() && Src.getValueType() == MVT::i64;
3388
3389 if (Src.getValueType() == MVT::i32 || Is64BitScalar) {
3390 // (ctlz hi:lo) -> (umin (ffbh src), 32)
3391 // (cttz hi:lo) -> (umin (ffbl src), 32)
3392 // (ctlz_zero_poison src) -> (ffbh src)
3393 // (cttz_zero_poison src) -> (ffbl src)
3394
3395 // 64-bit scalar version produce 32-bit result
3396 // (ctlz hi:lo) -> (umin (S_FLBIT_I32_B64 src), 64)
3397 // (cttz hi:lo) -> (umin (S_FF1_I32_B64 src), 64)
3398 // (ctlz_zero_poison src) -> (S_FLBIT_I32_B64 src)
3399 // (cttz_zero_poison src) -> (S_FF1_I32_B64 src)
3400 SDValue NewOpr = DAG.getNode(NewOpc, SL, MVT::i32, Src);
3401 if (!ZeroUndef) {
3402 const SDValue ConstVal = DAG.getConstant(
3403 Op.getValueType().getScalarSizeInBits(), SL, MVT::i32);
3404 NewOpr = DAG.getNode(ISD::UMIN, SL, MVT::i32, NewOpr, ConstVal);
3405 }
3406 return DAG.getNode(ISD::ZERO_EXTEND, SL, Src.getValueType(), NewOpr);
3407 }
3408
3409 SDValue Lo, Hi;
3410 std::tie(Lo, Hi) = split64BitValue(Src, DAG);
3411
3412 SDValue OprLo = DAG.getNode(NewOpc, SL, MVT::i32, Lo);
3413 SDValue OprHi = DAG.getNode(NewOpc, SL, MVT::i32, Hi);
3414
3415 // (ctlz hi:lo) -> (umin3 (ffbh hi), (uaddsat (ffbh lo), 32), 64)
3416 // (cttz hi:lo) -> (umin3 (uaddsat (ffbl hi), 32), (ffbl lo), 64)
3417 // (ctlz_zero_poison hi:lo) -> (umin (ffbh hi), (add (ffbh lo), 32))
3418 // (cttz_zero_poison hi:lo) -> (umin (add (ffbl hi), 32), (ffbl lo))
3419
3420 unsigned AddOpc = ZeroUndef ? ISD::ADD : ISD::UADDSAT;
3421 const SDValue Const32 = DAG.getConstant(32, SL, MVT::i32);
3422 if (Ctlz)
3423 OprLo = DAG.getNode(AddOpc, SL, MVT::i32, OprLo, Const32);
3424 else
3425 OprHi = DAG.getNode(AddOpc, SL, MVT::i32, OprHi, Const32);
3426
3427 SDValue NewOpr;
3428 NewOpr = DAG.getNode(ISD::UMIN, SL, MVT::i32, OprLo, OprHi);
3429 if (!ZeroUndef) {
3430 const SDValue Const64 = DAG.getConstant(64, SL, MVT::i32);
3431 NewOpr = DAG.getNode(ISD::UMIN, SL, MVT::i32, NewOpr, Const64);
3432 }
3433
3434 return DAG.getNode(ISD::ZERO_EXTEND, SL, MVT::i64, NewOpr);
3435}
3436
3438 SDLoc SL(Op);
3439 SDValue Src = Op.getOperand(0);
3440 assert(Src.getValueType() == MVT::i32 && "LowerCTLS only supports i32");
3441 SDValue Ffbh = DAG.getNode(
3442 ISD::INTRINSIC_WO_CHAIN, SL, MVT::i32,
3443 DAG.getTargetConstant(Intrinsic::amdgcn_sffbh, SL, MVT::i32), Src);
3444 SDValue Clamped = DAG.getNode(ISD::UMIN, SL, MVT::i32, Ffbh,
3445 DAG.getConstant(32, SL, MVT::i32));
3446 return DAG.getNode(ISD::ADD, SL, MVT::i32, Clamped,
3447 DAG.getAllOnesConstant(SL, MVT::i32));
3448}
3449
3451 EVT FP16Ty) const {
3452 assert(FP16Ty == MVT::f16 || FP16Ty == MVT::bf16);
3453 SDLoc SL(Op);
3454 SDValue Src = Op.getOperand(0);
3455 SDValue ToF32 = DAG.getNode(Op.getOpcode(), SL, MVT::f32, Src);
3456 SDValue FPRoundFlag = DAG.getIntPtrConstant(0, SL, /*isTarget=*/true);
3457 return DAG.getNode(ISD::FP_ROUND, SL, FP16Ty, ToF32, FPRoundFlag);
3458}
3459
3461 bool Signed) const {
3462 // The regular method converting a 64-bit integer to float roughly consists of
3463 // 2 steps: normalization and rounding. In fact, after normalization, the
3464 // conversion from a 64-bit integer to a float is essentially the same as the
3465 // one from a 32-bit integer. The only difference is that it has more
3466 // trailing bits to be rounded. To leverage the native 32-bit conversion, a
3467 // 64-bit integer could be preprocessed and fit into a 32-bit integer then
3468 // converted into the correct float number. The basic steps for the unsigned
3469 // conversion are illustrated in the following pseudo code:
3470 //
3471 // f32 uitofp(i64 u) {
3472 // i32 hi, lo = split(u);
3473 // // Only count the leading zeros in hi as we have native support of the
3474 // // conversion from i32 to f32. If hi is all 0s, the conversion is
3475 // // reduced to a 32-bit one automatically.
3476 // i32 shamt = clz(hi); // Return 32 if hi is all 0s.
3477 // u <<= shamt;
3478 // hi, lo = split(u);
3479 // hi |= (lo != 0) ? 1 : 0; // Adjust rounding bit in hi based on lo.
3480 // // convert it as a 32-bit integer and scale the result back.
3481 // return uitofp(hi) * 2^(32 - shamt);
3482 // }
3483 //
3484 // The signed one follows the same principle but uses 'ffbh_i32' to count its
3485 // sign bits instead. If 'ffbh_i32' is not available, its absolute value is
3486 // converted instead followed by negation based its sign bit.
3487
3488 SDLoc SL(Op);
3489 SDValue Src = Op.getOperand(0);
3490
3491 SDValue Lo, Hi;
3492 std::tie(Lo, Hi) = split64BitValue(Src, DAG);
3493 SDValue Sign;
3494 SDValue ShAmt;
3495 if (Signed && Subtarget->isGCN()) {
3496 // We also need to consider the sign bit in Lo if Hi has just sign bits,
3497 // i.e. Hi is 0 or -1. However, that only needs to take the MSB into
3498 // account. That is, the maximal shift is
3499 // - 32 if Lo and Hi have opposite signs;
3500 // - 33 if Lo and Hi have the same sign.
3501 //
3502 // Or, MaxShAmt = 33 + OppositeSign, where
3503 //
3504 // OppositeSign is defined as ((Lo ^ Hi) >> 31), which is
3505 // - -1 if Lo and Hi have opposite signs; and
3506 // - 0 otherwise.
3507 //
3508 // All in all, ShAmt is calculated as
3509 //
3510 // umin(sffbh(Hi), 33 + (Lo^Hi)>>31) - 1.
3511 //
3512 // or
3513 //
3514 // umin(sffbh(Hi) - 1, 32 + (Lo^Hi)>>31).
3515 //
3516 // to reduce the critical path.
3517 SDValue OppositeSign = DAG.getNode(
3518 ISD::SRA, SL, MVT::i32, DAG.getNode(ISD::XOR, SL, MVT::i32, Lo, Hi),
3519 DAG.getConstant(31, SL, MVT::i32));
3520 SDValue MaxShAmt =
3521 DAG.getNode(ISD::ADD, SL, MVT::i32, DAG.getConstant(32, SL, MVT::i32),
3522 OppositeSign);
3523 // Count the leading sign bits.
3524 ShAmt = DAG.getNode(
3525 ISD::INTRINSIC_WO_CHAIN, SL, MVT::i32,
3526 DAG.getTargetConstant(Intrinsic::amdgcn_sffbh, SL, MVT::i32), Hi);
3527 // Different from unsigned conversion, the shift should be one bit less to
3528 // preserve the sign bit.
3529 ShAmt = DAG.getNode(ISD::SUB, SL, MVT::i32, ShAmt,
3530 DAG.getConstant(1, SL, MVT::i32));
3531 ShAmt = DAG.getNode(ISD::UMIN, SL, MVT::i32, ShAmt, MaxShAmt);
3532 } else {
3533 if (Signed) {
3534 // Without 'ffbh_i32', only leading zeros could be counted. Take the
3535 // absolute value first.
3536 Sign = DAG.getNode(ISD::SRA, SL, MVT::i64, Src,
3537 DAG.getConstant(63, SL, MVT::i64));
3538 SDValue Abs =
3539 DAG.getNode(ISD::XOR, SL, MVT::i64,
3540 DAG.getNode(ISD::ADD, SL, MVT::i64, Src, Sign), Sign);
3541 std::tie(Lo, Hi) = split64BitValue(Abs, DAG);
3542 }
3543 // Count the leading zeros.
3544 ShAmt = DAG.getNode(ISD::CTLZ, SL, MVT::i32, Hi);
3545 // The shift amount for signed integers is [0, 32].
3546 }
3547 // Normalize the given 64-bit integer.
3548 SDValue Norm = DAG.getNode(ISD::SHL, SL, MVT::i64, Src, ShAmt);
3549 // Split it again.
3550 std::tie(Lo, Hi) = split64BitValue(Norm, DAG);
3551 // Calculate the adjust bit for rounding.
3552 // (lo != 0) ? 1 : 0 => (lo >= 1) ? 1 : 0 => umin(1, lo)
3553 SDValue Adjust = DAG.getNode(ISD::UMIN, SL, MVT::i32,
3554 DAG.getConstant(1, SL, MVT::i32), Lo);
3555 // Get the 32-bit normalized integer.
3556 Norm = DAG.getNode(ISD::OR, SL, MVT::i32, Hi, Adjust);
3557 // Convert the normalized 32-bit integer into f32.
3558
3559 bool UseLDEXP = isOperationLegal(ISD::FLDEXP, MVT::f32);
3560 unsigned Opc = Signed && UseLDEXP ? ISD::SINT_TO_FP : ISD::UINT_TO_FP;
3561 SDValue FVal = DAG.getNode(Opc, SL, MVT::f32, Norm);
3562
3563 // Finally, need to scale back the converted floating number as the original
3564 // 64-bit integer is converted as a 32-bit one.
3565 ShAmt = DAG.getNode(ISD::SUB, SL, MVT::i32, DAG.getConstant(32, SL, MVT::i32),
3566 ShAmt);
3567 // On GCN, use LDEXP directly.
3568 if (UseLDEXP)
3569 return DAG.getNode(ISD::FLDEXP, SL, MVT::f32, FVal, ShAmt);
3570
3571 // Otherwise, align 'ShAmt' to the exponent part and add it into the exponent
3572 // part directly to emulate the multiplication of 2^ShAmt. That 8-bit
3573 // exponent is enough to avoid overflowing into the sign bit.
3574 SDValue Exp = DAG.getNode(ISD::SHL, SL, MVT::i32, ShAmt,
3575 DAG.getConstant(23, SL, MVT::i32));
3576 SDValue IVal =
3577 DAG.getNode(ISD::ADD, SL, MVT::i32,
3578 DAG.getNode(ISD::BITCAST, SL, MVT::i32, FVal), Exp);
3579 if (Signed) {
3580 // Set the sign bit.
3581 Sign = DAG.getNode(ISD::SHL, SL, MVT::i32,
3582 DAG.getNode(ISD::TRUNCATE, SL, MVT::i32, Sign),
3583 DAG.getConstant(31, SL, MVT::i32));
3584 IVal = DAG.getNode(ISD::OR, SL, MVT::i32, IVal, Sign);
3585 }
3586 return DAG.getNode(ISD::BITCAST, SL, MVT::f32, IVal);
3587}
3588
3590 bool Signed) const {
3591 SDLoc SL(Op);
3592 SDValue Src = Op.getOperand(0);
3593
3594 SDValue Lo, Hi;
3595 std::tie(Lo, Hi) = split64BitValue(Src, DAG);
3596
3598 SL, MVT::f64, Hi);
3599
3600 SDValue CvtLo = DAG.getNode(ISD::UINT_TO_FP, SL, MVT::f64, Lo);
3601
3602 SDValue LdExp = DAG.getNode(ISD::FLDEXP, SL, MVT::f64, CvtHi,
3603 DAG.getConstant(32, SL, MVT::i32));
3604 // TODO: Should this propagate fast-math-flags?
3605 return DAG.getNode(ISD::FADD, SL, MVT::f64, LdExp, CvtLo);
3606}
3607
3609 bool Signed) const {
3610 EVT DestVT = Op.getValueType();
3611 SDValue Src = Op.getOperand(0);
3612 EVT SrcVT = Src.getValueType();
3613 unsigned ExtOpc = Signed ? ISD::SIGN_EXTEND : ISD::ZERO_EXTEND;
3614 unsigned CvtOpc = Signed ? ISD::SINT_TO_FP : ISD::UINT_TO_FP;
3615
3616 if (SrcVT == MVT::i16) {
3617 if (DestVT == MVT::f16)
3618 return Op;
3619
3620 SDLoc DL(Op);
3621 SDValue Ext = DAG.getNode(ExtOpc, DL, MVT::i32, Src);
3622 return DAG.getNode(CvtOpc, DL, DestVT, Ext);
3623 }
3624
3625 if (DestVT == MVT::bf16 || DestVT == MVT::f16)
3626 return LowerINT_TO_FP16(Op, DAG, DestVT);
3627
3628 if (SrcVT != MVT::i64)
3629 return Op;
3630
3631 if (DestVT == MVT::f32)
3632 return LowerINT_TO_FP32(Op, DAG, Signed);
3633
3634 assert(DestVT == MVT::f64);
3635 return LowerINT_TO_FP64(Op, DAG, Signed);
3636}
3637
3642
3647
3649 bool Signed) const {
3650 SDLoc SL(Op);
3651
3652 SDValue Src = Op.getOperand(0);
3653 EVT SrcVT = Src.getValueType();
3654
3655 assert(SrcVT == MVT::f32 || SrcVT == MVT::f64);
3656
3657 // The basic idea of converting a floating point number into a pair of 32-bit
3658 // integers is illustrated as follows:
3659 //
3660 // tf := trunc(val);
3661 // hif := floor(tf * 2^-32);
3662 // lof := tf - hif * 2^32; // lof is always positive due to floor.
3663 // hi := fptoi(hif);
3664 // lo := fptoi(lof);
3665 //
3666 SDValue Trunc = DAG.getNode(ISD::FTRUNC, SL, SrcVT, Src);
3667 SDValue Sign;
3668 if (Signed && SrcVT == MVT::f32) {
3669 // However, a 32-bit floating point number has only 23 bits mantissa and
3670 // it's not enough to hold all the significant bits of `lof` if val is
3671 // negative. To avoid the loss of precision, We need to take the absolute
3672 // value after truncating and flip the result back based on the original
3673 // signedness.
3674 Sign = DAG.getNode(ISD::SRA, SL, MVT::i32,
3675 DAG.getNode(ISD::BITCAST, SL, MVT::i32, Trunc),
3676 DAG.getConstant(31, SL, MVT::i32));
3677 Trunc = DAG.getNode(ISD::FABS, SL, SrcVT, Trunc);
3678 }
3679
3680 SDValue K0, K1;
3681 if (SrcVT == MVT::f64) {
3682 K0 = DAG.getConstantFP(
3683 llvm::bit_cast<double>(UINT64_C(/*2^-32*/ 0x3df0000000000000)), SL,
3684 SrcVT);
3685 K1 = DAG.getConstantFP(
3686 llvm::bit_cast<double>(UINT64_C(/*-2^32*/ 0xc1f0000000000000)), SL,
3687 SrcVT);
3688 } else {
3689 K0 = DAG.getConstantFP(
3690 llvm::bit_cast<float>(UINT32_C(/*2^-32*/ 0x2f800000)), SL, SrcVT);
3691 K1 = DAG.getConstantFP(
3692 llvm::bit_cast<float>(UINT32_C(/*-2^32*/ 0xcf800000)), SL, SrcVT);
3693 }
3694 // TODO: Should this propagate fast-math-flags?
3695 SDValue Mul = DAG.getNode(ISD::FMUL, SL, SrcVT, Trunc, K0);
3696
3697 SDValue FloorMul = DAG.getNode(ISD::FFLOOR, SL, SrcVT, Mul);
3698
3699 SDValue Fma = DAG.getNode(ISD::FMA, SL, SrcVT, FloorMul, K1, Trunc);
3700
3701 SDValue Hi = DAG.getNode((Signed && SrcVT == MVT::f64) ? ISD::FP_TO_SINT
3703 SL, MVT::i32, FloorMul);
3704 SDValue Lo = DAG.getNode(ISD::FP_TO_UINT, SL, MVT::i32, Fma);
3705
3706 SDValue Result = DAG.getNode(ISD::BITCAST, SL, MVT::i64,
3707 DAG.getBuildVector(MVT::v2i32, SL, {Lo, Hi}));
3708
3709 if (Signed && SrcVT == MVT::f32) {
3710 assert(Sign);
3711 // Flip the result based on the signedness, which is either all 0s or 1s.
3712 Sign = DAG.getNode(ISD::BITCAST, SL, MVT::i64,
3713 DAG.getBuildVector(MVT::v2i32, SL, {Sign, Sign}));
3714 // r := xor(r, sign) - sign;
3715 Result =
3716 DAG.getNode(ISD::SUB, SL, MVT::i64,
3717 DAG.getNode(ISD::XOR, SL, MVT::i64, Result, Sign), Sign);
3718 }
3719
3720 return Result;
3721}
3722
3724 SDLoc DL(Op);
3725 SDValue N0 = Op.getOperand(0);
3726
3727 // Convert to target node to get known bits
3728 if (N0.getValueType() == MVT::f32)
3729 return DAG.getNode(AMDGPUISD::FP_TO_FP16, DL, Op.getValueType(), N0);
3730
3731 if (Op->getFlags().hasApproximateFuncs()) {
3732 // There is a generic expand for FP_TO_FP16 with unsafe fast math.
3733 return SDValue();
3734 }
3735
3736 return LowerF64ToF16Safe(N0, DL, DAG);
3737}
3738
3739// return node in i32
3741 SelectionDAG &DAG) const {
3742 assert(Src.getSimpleValueType() == MVT::f64);
3743
3744 // f64 -> f16 conversion using round-to-nearest-even rounding mode.
3745 // TODO: We can generate better code for True16.
3746 const unsigned ExpMask = 0x7ff;
3747 const unsigned ExpBiasf64 = 1023;
3748 const unsigned ExpBiasf16 = 15;
3749 SDValue Zero = DAG.getConstant(0, DL, MVT::i32);
3750 SDValue One = DAG.getConstant(1, DL, MVT::i32);
3751 SDValue U = DAG.getNode(ISD::BITCAST, DL, MVT::i64, Src);
3752 SDValue UH = DAG.getNode(ISD::SRL, DL, MVT::i64, U,
3753 DAG.getConstant(32, DL, MVT::i64));
3754 UH = DAG.getZExtOrTrunc(UH, DL, MVT::i32);
3755 U = DAG.getZExtOrTrunc(U, DL, MVT::i32);
3756 SDValue E = DAG.getNode(ISD::SRL, DL, MVT::i32, UH,
3757 DAG.getConstant(20, DL, MVT::i64));
3758 E = DAG.getNode(ISD::AND, DL, MVT::i32, E,
3759 DAG.getConstant(ExpMask, DL, MVT::i32));
3760 // Subtract the fp64 exponent bias (1023) to get the real exponent and
3761 // add the f16 bias (15) to get the biased exponent for the f16 format.
3762 E = DAG.getNode(ISD::ADD, DL, MVT::i32, E,
3763 DAG.getConstant(-ExpBiasf64 + ExpBiasf16, DL, MVT::i32));
3764
3765 SDValue M = DAG.getNode(ISD::SRL, DL, MVT::i32, UH,
3766 DAG.getConstant(8, DL, MVT::i32));
3767 M = DAG.getNode(ISD::AND, DL, MVT::i32, M,
3768 DAG.getConstant(0xffe, DL, MVT::i32));
3769
3770 SDValue MaskedSig = DAG.getNode(ISD::AND, DL, MVT::i32, UH,
3771 DAG.getConstant(0x1ff, DL, MVT::i32));
3772 MaskedSig = DAG.getNode(ISD::OR, DL, MVT::i32, MaskedSig, U);
3773
3774 SDValue Lo40Set = DAG.getSelectCC(DL, MaskedSig, Zero, Zero, One, ISD::SETEQ);
3775 M = DAG.getNode(ISD::OR, DL, MVT::i32, M, Lo40Set);
3776
3777 // (M != 0 ? 0x0200 : 0) | 0x7c00;
3778 SDValue I = DAG.getNode(ISD::OR, DL, MVT::i32,
3779 DAG.getSelectCC(DL, M, Zero, DAG.getConstant(0x0200, DL, MVT::i32),
3780 Zero, ISD::SETNE), DAG.getConstant(0x7c00, DL, MVT::i32));
3781
3782 // N = M | (E << 12);
3783 SDValue N = DAG.getNode(ISD::OR, DL, MVT::i32, M,
3784 DAG.getNode(ISD::SHL, DL, MVT::i32, E,
3785 DAG.getConstant(12, DL, MVT::i32)));
3786
3787 // B = clamp(1-E, 0, 13);
3788 SDValue OneSubExp = DAG.getNode(ISD::SUB, DL, MVT::i32,
3789 One, E);
3790 SDValue B = DAG.getNode(ISD::SMAX, DL, MVT::i32, OneSubExp, Zero);
3791 B = DAG.getNode(ISD::SMIN, DL, MVT::i32, B,
3792 DAG.getConstant(13, DL, MVT::i32));
3793
3794 SDValue SigSetHigh = DAG.getNode(ISD::OR, DL, MVT::i32, M,
3795 DAG.getConstant(0x1000, DL, MVT::i32));
3796
3797 SDValue D = DAG.getNode(ISD::SRL, DL, MVT::i32, SigSetHigh, B);
3798 SDValue D0 = DAG.getNode(ISD::SHL, DL, MVT::i32, D, B);
3799 SDValue D1 = DAG.getSelectCC(DL, D0, SigSetHigh, One, Zero, ISD::SETNE);
3800 D = DAG.getNode(ISD::OR, DL, MVT::i32, D, D1);
3801
3802 SDValue V = DAG.getSelectCC(DL, E, One, D, N, ISD::SETLT);
3803 SDValue VLow3 = DAG.getNode(ISD::AND, DL, MVT::i32, V,
3804 DAG.getConstant(0x7, DL, MVT::i32));
3805 V = DAG.getNode(ISD::SRL, DL, MVT::i32, V,
3806 DAG.getConstant(2, DL, MVT::i32));
3807 SDValue V0 = DAG.getSelectCC(DL, VLow3, DAG.getConstant(3, DL, MVT::i32),
3808 One, Zero, ISD::SETEQ);
3809 SDValue V1 = DAG.getSelectCC(DL, VLow3, DAG.getConstant(5, DL, MVT::i32),
3810 One, Zero, ISD::SETGT);
3811 V1 = DAG.getNode(ISD::OR, DL, MVT::i32, V0, V1);
3812 V = DAG.getNode(ISD::ADD, DL, MVT::i32, V, V1);
3813
3814 V = DAG.getSelectCC(DL, E, DAG.getConstant(30, DL, MVT::i32),
3815 DAG.getConstant(0x7c00, DL, MVT::i32), V, ISD::SETGT);
3816 V = DAG.getSelectCC(DL, E, DAG.getConstant(1039, DL, MVT::i32),
3817 I, V, ISD::SETEQ);
3818
3819 // Extract the sign bit.
3820 SDValue Sign = DAG.getNode(ISD::SRL, DL, MVT::i32, UH,
3821 DAG.getConstant(16, DL, MVT::i32));
3822 Sign = DAG.getNode(ISD::AND, DL, MVT::i32, Sign,
3823 DAG.getConstant(0x8000, DL, MVT::i32));
3824
3825 return DAG.getNode(ISD::OR, DL, MVT::i32, Sign, V);
3826}
3827
3829 SelectionDAG &DAG) const {
3830 SDValue Src = Op.getOperand(0);
3831 unsigned OpOpcode = Op.getOpcode();
3832 EVT SrcVT = Src.getValueType();
3833 EVT DestVT = Op.getValueType();
3834
3835 // Will be selected natively
3836 if (SrcVT == MVT::f16 && DestVT == MVT::i16)
3837 return Op;
3838
3839 if (SrcVT == MVT::bf16 || (SrcVT == MVT::f16 && DestVT == MVT::i32)) {
3840 SDLoc DL(Op);
3841 SDValue PromotedSrc = DAG.getNode(ISD::FP_EXTEND, DL, MVT::f32, Src);
3842 return DAG.getNode(Op.getOpcode(), DL, DestVT, PromotedSrc);
3843 }
3844
3845 // Promote i16 to i32
3846 if (DestVT == MVT::i16 && (SrcVT == MVT::f32 || SrcVT == MVT::f64)) {
3847 SDLoc DL(Op);
3848
3849 SDValue FpToInt32 = DAG.getNode(OpOpcode, DL, MVT::i32, Src);
3850 return DAG.getNode(ISD::TRUNCATE, DL, MVT::i16, FpToInt32);
3851 }
3852
3853 if (DestVT != MVT::i64)
3854 return Op;
3855
3856 if (SrcVT == MVT::f16 ||
3857 (SrcVT == MVT::f32 && Src.getOpcode() == ISD::FP16_TO_FP)) {
3858 SDLoc DL(Op);
3859
3860 SDValue FpToInt32 = DAG.getNode(OpOpcode, DL, MVT::i32, Src);
3861 unsigned Ext =
3863 return DAG.getNode(Ext, DL, MVT::i64, FpToInt32);
3864 }
3865
3866 if (SrcVT == MVT::f32 || SrcVT == MVT::f64)
3867 return LowerFP_TO_INT64(Op, DAG, OpOpcode == ISD::FP_TO_SINT);
3868
3869 return SDValue();
3870}
3871
3873 SelectionDAG &DAG) const {
3874 SDValue Src = Op.getOperand(0);
3875 unsigned OpOpcode = Op.getOpcode();
3876 EVT SrcVT = Src.getValueType();
3877 EVT DstVT = Op.getValueType();
3878 SDValue SatVTOp = Op.getNode()->getOperand(1);
3879 EVT SatVT = cast<VTSDNode>(SatVTOp)->getVT();
3880 SDLoc DL(Op);
3881
3882 uint64_t DstWidth = DstVT.getScalarSizeInBits();
3883 uint64_t SatWidth = SatVT.getScalarSizeInBits();
3884 assert(SatWidth <= DstWidth && "Saturation width cannot exceed result width");
3885
3886 // Scalar cases will be selected natively to v_cvt_/s_cvt_ instructions.
3887 // v2f32 -> v2i16 will be selected natively to v_cvt_pk_[iu]16_f32.
3888 if (SatWidth == DstWidth) {
3889 if ((DstVT == MVT::i32 && (SrcVT == MVT::f32 || SrcVT == MVT::f64)) ||
3890 (DstVT == MVT::i16 && (SrcVT == MVT::f16 || SrcVT == MVT::f32)) ||
3891 (DstVT == MVT::v2i16 && SrcVT == MVT::v2f32))
3892 return Op;
3893 }
3894
3895 // Vectors can only be selected natively.
3896 if (DstVT.isVector())
3897 return SDValue();
3898
3899 // Perform all saturation at selected width (i16 or i32) and truncate
3900 if (SatWidth < DstWidth && SatWidth <= 32) {
3901 // For f16 conversion with sub-i16 saturation perform saturation
3902 // at i16, if available in the target. This removes the need for extra f16
3903 // to f32 conversion. For all the others use i32.
3904 MVT ResultVT =
3905 Subtarget->has16BitInsts() && SrcVT == MVT::f16 && SatWidth < 16
3906 ? MVT::i16
3907 : MVT::i32;
3908
3909 const SDValue ResultVTOp = DAG.getValueType(ResultVT);
3910 const uint64_t ResultWidth = ResultVT.getScalarSizeInBits();
3911
3912 // First, convert input float into selected integer (i16 or i32)
3913 SDValue FpToInt = DAG.getNode(OpOpcode, DL, ResultVT, Src, ResultVTOp);
3914 SDValue IntSatVal;
3915
3916 // Then, clamp at the saturation width using either i16 or i32 instructions
3917 if (OpOpcode == ISD::FP_TO_SINT_SAT) {
3918 SDValue MinConst = DAG.getConstant(
3919 APInt::getSignedMaxValue(SatWidth).sext(ResultWidth), DL, ResultVT);
3920 SDValue MaxConst = DAG.getConstant(
3921 APInt::getSignedMinValue(SatWidth).sext(ResultWidth), DL, ResultVT);
3922 SDValue MinVal = DAG.getNode(ISD::SMIN, DL, ResultVT, FpToInt, MinConst);
3923 IntSatVal = DAG.getNode(ISD::SMAX, DL, ResultVT, MinVal, MaxConst);
3924 } else {
3925 SDValue MinConst = DAG.getConstant(
3926 APInt::getMaxValue(SatWidth).zext(ResultWidth), DL, ResultVT);
3927 IntSatVal = DAG.getNode(ISD::UMIN, DL, ResultVT, FpToInt, MinConst);
3928 }
3929
3930 // Finally, after saturating at i16 or i32 fit into the destination type
3931 return DAG.getExtOrTrunc(OpOpcode == ISD::FP_TO_SINT_SAT, IntSatVal, DL,
3932 DstVT);
3933 }
3934
3935 // SatWidth == DstWidth or SatWidth > 32
3936
3937 // Saturate at i32 for i64 dst and f16/bf16 src (will invoke f16 promotion
3938 // below)
3939 if (DstVT == MVT::i64 &&
3940 (SrcVT == MVT::f16 || SrcVT == MVT::bf16 ||
3941 (SrcVT == MVT::f32 && Src.getOpcode() == ISD::FP16_TO_FP))) {
3942 const SDValue Int32VTOp = DAG.getValueType(MVT::i32);
3943 return DAG.getNode(OpOpcode, DL, DstVT, Src, Int32VTOp);
3944 }
3945
3946 // Promote f16/bf16 src to f32 for i32 conversion
3947 if (DstVT == MVT::i32 && (SrcVT == MVT::f16 || SrcVT == MVT::bf16)) {
3948 SDValue PromotedSrc = DAG.getNode(ISD::FP_EXTEND, DL, MVT::f32, Src);
3949 return DAG.getNode(Op.getOpcode(), DL, DstVT, PromotedSrc, SatVTOp);
3950 }
3951
3952 // For DstWidth < 16, promote i1 and i8 dst to i16 (if legal) with sub-i16
3953 // saturation. For DstWidth == 16, promote i16 dst to i32 with sub-i32
3954 // saturation; this covers i16.f32 and i16.f64
3955 if (DstWidth < 32) {
3956 // Note: this triggers SatWidth < DstWidth above to generate saturated
3957 // truncate by requesting MVT::i16/i32 destination with SatWidth < 16/32.
3958 MVT PromoteVT =
3959 (DstWidth < 16 && Subtarget->has16BitInsts()) ? MVT::i16 : MVT::i32;
3960 SDValue FpToInt = DAG.getNode(OpOpcode, DL, PromoteVT, Src, SatVTOp);
3961 return DAG.getNode(ISD::TRUNCATE, DL, DstVT, FpToInt);
3962 }
3963
3964 // TODO: can we implement i64 dst for f32/f64?
3965
3966 return SDValue();
3967}
3968
3970 SelectionDAG &DAG) const {
3971 EVT ExtraVT = cast<VTSDNode>(Op.getOperand(1))->getVT();
3972 MVT VT = Op.getSimpleValueType();
3973 MVT ScalarVT = VT.getScalarType();
3974
3975 assert(VT.isVector());
3976
3977 SDValue Src = Op.getOperand(0);
3978 SDLoc DL(Op);
3979
3980 // TODO: Don't scalarize on Evergreen?
3981 unsigned NElts = VT.getVectorNumElements();
3983 DAG.ExtractVectorElements(Src, Args, 0, NElts);
3984
3985 SDValue VTOp = DAG.getValueType(ExtraVT.getScalarType());
3986 for (unsigned I = 0; I < NElts; ++I)
3987 Args[I] = DAG.getNode(ISD::SIGN_EXTEND_INREG, DL, ScalarVT, Args[I], VTOp);
3988
3989 return DAG.getBuildVector(VT, DL, Args);
3990}
3991
3992//===----------------------------------------------------------------------===//
3993// Custom DAG optimizations
3994//===----------------------------------------------------------------------===//
3995
3996static bool isU24(SDValue Op, SelectionDAG &DAG) {
3997 return AMDGPUTargetLowering::numBitsUnsigned(Op, DAG) <= 24;
3998}
3999
4000static bool isI24(SDValue Op, SelectionDAG &DAG) {
4001 EVT VT = Op.getValueType();
4002 return VT.getSizeInBits() >= 24 && // Types less than 24-bit should be treated
4003 // as unsigned 24-bit values.
4005}
4006
4009 SelectionDAG &DAG = DCI.DAG;
4010 const TargetLowering &TLI = DAG.getTargetLoweringInfo();
4011 bool IsIntrin = Node24->getOpcode() == ISD::INTRINSIC_WO_CHAIN;
4012
4013 SDValue LHS = IsIntrin ? Node24->getOperand(1) : Node24->getOperand(0);
4014 SDValue RHS = IsIntrin ? Node24->getOperand(2) : Node24->getOperand(1);
4015 unsigned NewOpcode = Node24->getOpcode();
4016 if (IsIntrin) {
4017 unsigned IID = Node24->getConstantOperandVal(0);
4018 switch (IID) {
4019 case Intrinsic::amdgcn_mul_i24:
4020 NewOpcode = AMDGPUISD::MUL_I24;
4021 break;
4022 case Intrinsic::amdgcn_mul_u24:
4023 NewOpcode = AMDGPUISD::MUL_U24;
4024 break;
4025 case Intrinsic::amdgcn_mulhi_i24:
4026 NewOpcode = AMDGPUISD::MULHI_I24;
4027 break;
4028 case Intrinsic::amdgcn_mulhi_u24:
4029 NewOpcode = AMDGPUISD::MULHI_U24;
4030 break;
4031 default:
4032 llvm_unreachable("Expected 24-bit mul intrinsic");
4033 }
4034 }
4035
4036 APInt Demanded = APInt::getLowBitsSet(LHS.getValueSizeInBits(), 24);
4037
4039 return DAG.getConstant(0, SDLoc(Node24), Node24->getValueType(0));
4040
4041 // First try SimplifyDemandedBits which can simplify the nodes used by our
4042 // operands if this node is the only user.
4043 if (LHS.hasOneUse() && TLI.SimplifyDemandedBits(LHS, Demanded, DCI))
4044 return SDValue(Node24, 0);
4045 if (RHS.hasOneUse() && TLI.SimplifyDemandedBits(RHS, Demanded, DCI))
4046 return SDValue(Node24, 0);
4047
4048 // Then try SimplifyMultipleUseDemandedBits which allows the operands to have
4049 // other uses, but will only perform simplifications that involve bypassing
4050 // some nodes for this user.
4051 SDValue DemandedLHS = TLI.SimplifyMultipleUseDemandedBits(LHS, Demanded, DAG);
4052 SDValue DemandedRHS = TLI.SimplifyMultipleUseDemandedBits(RHS, Demanded, DAG);
4053 if (DemandedLHS || DemandedRHS)
4054 return DAG.getNode(NewOpcode, SDLoc(Node24), Node24->getVTList(),
4055 DemandedLHS ? DemandedLHS : LHS,
4056 DemandedRHS ? DemandedRHS : RHS);
4057
4058 return SDValue();
4059}
4060
4061template <typename IntTy>
4063 uint32_t Width, const SDLoc &DL) {
4064 if (Width + Offset < 32) {
4065 uint32_t Shl = static_cast<uint32_t>(Src0) << (32 - Offset - Width);
4066 IntTy Result = static_cast<IntTy>(Shl) >> (32 - Width);
4067 if constexpr (std::is_signed_v<IntTy>) {
4068 return DAG.getSignedConstant(Result, DL, MVT::i32);
4069 } else {
4070 return DAG.getConstant(Result, DL, MVT::i32);
4071 }
4072 }
4073
4074 return DAG.getConstant(Src0 >> Offset, DL, MVT::i32);
4075}
4076
4077static bool hasVolatileUser(SDNode *Val) {
4078 for (SDNode *U : Val->users()) {
4079 if (MemSDNode *M = dyn_cast<MemSDNode>(U)) {
4080 if (M->isVolatile())
4081 return true;
4082 }
4083 }
4084
4085 return false;
4086}
4087
4089 // i32 vectors are the canonical memory type.
4090 if (VT.getScalarType() == MVT::i32 || isTypeLegal(VT))
4091 return false;
4092
4093 if (!VT.isByteSized())
4094 return false;
4095
4096 unsigned Size = VT.getStoreSize();
4097
4098 if ((Size == 1 || Size == 2 || Size == 4) && !VT.isVector())
4099 return false;
4100
4101 if (Size == 3 || (Size > 4 && (Size % 4 != 0)))
4102 return false;
4103
4104 return true;
4105}
4106
4107// Replace load of an illegal type with a bitcast from a load of a friendlier
4108// type.
4110 DAGCombinerInfo &DCI) const {
4111 if (!DCI.isBeforeLegalize())
4112 return SDValue();
4113
4115 if (!LN->isSimple() || !ISD::isNormalLoad(LN) || hasVolatileUser(LN))
4116 return SDValue();
4117
4118 SDLoc SL(N);
4119 SelectionDAG &DAG = DCI.DAG;
4120 EVT VT = LN->getMemoryVT();
4121
4122 unsigned Size = VT.getStoreSize();
4123 Align Alignment = LN->getAlign();
4124 if (Alignment < Size && isTypeLegal(VT)) {
4125 unsigned IsFast;
4126 unsigned AS = LN->getAddressSpace();
4127
4128 // Expand unaligned loads earlier than legalization. Due to visitation order
4129 // problems during legalization, the emitted instructions to pack and unpack
4130 // the bytes again are not eliminated in the case of an unaligned copy.
4132 VT, AS, Alignment, LN->getMemOperand()->getFlags(), &IsFast)) {
4133 if (VT.isVector())
4134 return SplitVectorLoad(SDValue(LN, 0), DAG);
4135
4136 SDValue Ops[2];
4137 std::tie(Ops[0], Ops[1]) = expandUnalignedLoad(LN, DAG);
4138
4139 return DAG.getMergeValues(Ops, SDLoc(N));
4140 }
4141
4142 if (!IsFast)
4143 return SDValue();
4144 }
4145
4146 if (!shouldCombineMemoryType(VT))
4147 return SDValue();
4148
4149 EVT NewVT = getEquivalentMemType(*DAG.getContext(), VT);
4150
4151 SDValue NewLoad
4152 = DAG.getLoad(NewVT, SL, LN->getChain(),
4153 LN->getBasePtr(), LN->getMemOperand());
4154
4155 SDValue BC = DAG.getNode(ISD::BITCAST, SL, VT, NewLoad);
4156 DCI.CombineTo(N, BC, NewLoad.getValue(1));
4157 return SDValue(N, 0);
4158}
4159
4160// Replace store of an illegal type with a store of a bitcast to a friendlier
4161// type.
4163 DAGCombinerInfo &DCI) const {
4164 if (!DCI.isBeforeLegalize())
4165 return SDValue();
4166
4168 if (!SN->isSimple() || !ISD::isNormalStore(SN))
4169 return SDValue();
4170
4171 EVT VT = SN->getMemoryVT();
4172 unsigned Size = VT.getStoreSize();
4173
4174 SDLoc SL(N);
4175 SelectionDAG &DAG = DCI.DAG;
4176 Align Alignment = SN->getAlign();
4177 if (Alignment < Size && isTypeLegal(VT)) {
4178 unsigned IsFast;
4179 unsigned AS = SN->getAddressSpace();
4180
4181 // Expand unaligned stores earlier than legalization. Due to visitation
4182 // order problems during legalization, the emitted instructions to pack and
4183 // unpack the bytes again are not eliminated in the case of an unaligned
4184 // copy.
4186 VT, AS, Alignment, SN->getMemOperand()->getFlags(), &IsFast)) {
4187 if (VT.isVector())
4188 return SplitVectorStore(SDValue(SN, 0), DAG);
4189
4190 return expandUnalignedStore(SN, DAG);
4191 }
4192
4193 if (!IsFast)
4194 return SDValue();
4195 }
4196
4197 if (!shouldCombineMemoryType(VT))
4198 return SDValue();
4199
4200 EVT NewVT = getEquivalentMemType(*DAG.getContext(), VT);
4201 SDValue Val = SN->getValue();
4202
4203 // DCI.AddToWorklist(Val.getNode());
4204
4205 bool OtherUses = !Val.hasOneUse();
4206 SDValue CastVal = DAG.getBitcast(NewVT, Val);
4207 if (OtherUses) {
4208 SDValue CastBack = DAG.getBitcast(VT, CastVal);
4209 DAG.ReplaceAllUsesOfValueWith(Val, CastBack);
4210 }
4211
4212 return DAG.getStore(SN->getChain(), SL, CastVal,
4213 SN->getBasePtr(), SN->getMemOperand());
4214}
4215
4216// FIXME: This should go in generic DAG combiner with an isTruncateFree check,
4217// but isTruncateFree is inaccurate for i16 now because of SALU vs. VALU
4218// issues.
4220 DAGCombinerInfo &DCI) const {
4221 SelectionDAG &DAG = DCI.DAG;
4222 SDValue N0 = N->getOperand(0);
4223
4224 // (vt2 (assertzext (truncate vt0:x), vt1)) ->
4225 // (vt2 (truncate (assertzext vt0:x, vt1)))
4226 if (N0.getOpcode() == ISD::TRUNCATE) {
4227 SDValue N1 = N->getOperand(1);
4228 EVT ExtVT = cast<VTSDNode>(N1)->getVT();
4229 SDLoc SL(N);
4230
4231 SDValue Src = N0.getOperand(0);
4232 EVT SrcVT = Src.getValueType();
4233 if (SrcVT.bitsGE(ExtVT)) {
4234 SDValue NewInReg = DAG.getNode(N->getOpcode(), SL, SrcVT, Src, N1);
4235 return DAG.getNode(ISD::TRUNCATE, SL, N->getValueType(0), NewInReg);
4236 }
4237 }
4238
4239 return SDValue();
4240}
4241
4243 SDNode *N, DAGCombinerInfo &DCI) const {
4244 unsigned IID = N->getConstantOperandVal(0);
4245 switch (IID) {
4246 case Intrinsic::amdgcn_mul_i24:
4247 case Intrinsic::amdgcn_mul_u24:
4248 case Intrinsic::amdgcn_mulhi_i24:
4249 case Intrinsic::amdgcn_mulhi_u24:
4250 return simplifyMul24(N, DCI);
4251 case Intrinsic::amdgcn_fract:
4252 case Intrinsic::amdgcn_rsq:
4253 case Intrinsic::amdgcn_rcp_legacy:
4254 case Intrinsic::amdgcn_rsq_legacy:
4255 case Intrinsic::amdgcn_rsq_clamp:
4256 case Intrinsic::amdgcn_tanh:
4257 case Intrinsic::amdgcn_prng_b32: {
4258 // FIXME: This is probably wrong. If src is an sNaN, it won't be quieted
4259 SDValue Src = N->getOperand(1);
4260 return Src.isUndef() ? Src : SDValue();
4261 }
4262 case Intrinsic::amdgcn_frexp_exp: {
4263 // frexp_exp (fneg x) -> frexp_exp x
4264 // frexp_exp (fabs x) -> frexp_exp x
4265 // frexp_exp (fneg (fabs x)) -> frexp_exp x
4266 SDValue Src = N->getOperand(1);
4267 SDValue PeekSign = peekFPSignOps(Src);
4268 if (PeekSign == Src)
4269 return SDValue();
4270 return SDValue(DCI.DAG.UpdateNodeOperands(N, N->getOperand(0), PeekSign),
4271 0);
4272 }
4273 default:
4274 return SDValue();
4275 }
4276}
4277
4278/// Split the 64-bit value \p LHS into two 32-bit components, and perform the
4279/// binary operation \p Opc to it with the corresponding constant operands.
4281 DAGCombinerInfo &DCI, const SDLoc &SL,
4282 unsigned Opc, SDValue LHS,
4283 uint32_t ValLo, uint32_t ValHi) const {
4284 SelectionDAG &DAG = DCI.DAG;
4285 SDValue Lo, Hi;
4286 std::tie(Lo, Hi) = split64BitValue(LHS, DAG);
4287
4288 SDValue LoRHS = DAG.getConstant(ValLo, SL, MVT::i32);
4289 SDValue HiRHS = DAG.getConstant(ValHi, SL, MVT::i32);
4290
4291 SDValue LoAnd = DAG.getNode(Opc, SL, MVT::i32, Lo, LoRHS);
4292 SDValue HiAnd = DAG.getNode(Opc, SL, MVT::i32, Hi, HiRHS);
4293
4294 // Re-visit the ands. It's possible we eliminated one of them and it could
4295 // simplify the vector.
4296 DCI.AddToWorklist(Lo.getNode());
4297 DCI.AddToWorklist(Hi.getNode());
4298
4299 SDValue Vec = DAG.getBuildVector(MVT::v2i32, SL, {LoAnd, HiAnd});
4300 return DAG.getNode(ISD::BITCAST, SL, MVT::i64, Vec);
4301}
4302
4304 DAGCombinerInfo &DCI) const {
4305 EVT VT = N->getValueType(0);
4306 SDValue LHS = N->getOperand(0);
4307 SDValue RHS = N->getOperand(1);
4309 SDLoc SL(N);
4310 SelectionDAG &DAG = DCI.DAG;
4311
4312 unsigned RHSVal;
4313 if (CRHS) {
4314 RHSVal = CRHS->getZExtValue();
4315 if (!RHSVal)
4316 return LHS;
4317
4318 switch (LHS->getOpcode()) {
4319 default:
4320 break;
4321 case ISD::ZERO_EXTEND:
4322 case ISD::SIGN_EXTEND:
4323 case ISD::ANY_EXTEND: {
4324 SDValue X = LHS->getOperand(0);
4325
4326 if (VT == MVT::i32 && RHSVal == 16 && X.getValueType() == MVT::i16 &&
4327 isOperationLegal(ISD::BUILD_VECTOR, MVT::v2i16)) {
4328 // Prefer build_vector as the canonical form if packed types are legal.
4329 // (shl ([asz]ext i16:x), 16 -> build_vector 0, x
4330 SDValue Vec = DAG.getBuildVector(
4331 MVT::v2i16, SL,
4332 {DAG.getConstant(0, SL, MVT::i16), LHS->getOperand(0)});
4333 return DAG.getNode(ISD::BITCAST, SL, MVT::i32, Vec);
4334 }
4335
4336 // shl (ext x) => zext (shl x), if shift does not overflow int
4337 if (VT != MVT::i64)
4338 break;
4340 unsigned LZ = Known.countMinLeadingZeros();
4341 if (LZ < RHSVal)
4342 break;
4343 EVT XVT = X.getValueType();
4344 SDValue Shl = DAG.getNode(ISD::SHL, SL, XVT, X, SDValue(CRHS, 0));
4345 return DAG.getZExtOrTrunc(Shl, SL, VT);
4346 }
4347 }
4348 }
4349
4350 if (VT.getScalarType() != MVT::i64)
4351 return SDValue();
4352
4353 // On some subtargets, 64-bit shift is a quarter rate instruction. In the
4354 // common case, splitting this into a move and a 32-bit shift is faster and
4355 // the same code size.
4356 KnownBits Known = DAG.computeKnownBits(RHS);
4357
4358 EVT ElementType = VT.getScalarType();
4359 EVT TargetScalarType = ElementType.getHalfSizedIntegerVT(*DAG.getContext());
4360 EVT TargetType = VT.changeElementType(*DAG.getContext(), TargetScalarType);
4361
4362 if (Known.getMinValue().getZExtValue() < TargetScalarType.getSizeInBits())
4363 return SDValue();
4364 SDValue ShiftAmt;
4365
4366 if (CRHS) {
4367 ShiftAmt = DAG.getConstant(RHSVal - TargetScalarType.getSizeInBits(), SL,
4368 TargetType);
4369 } else {
4370 SDValue TruncShiftAmt = DAG.getNode(ISD::TRUNCATE, SL, TargetType, RHS);
4371 const SDValue ShiftMask =
4372 DAG.getConstant(TargetScalarType.getSizeInBits() - 1, SL, TargetType);
4373 // This AND instruction will clamp out of bounds shift values.
4374 // It will also be removed during later instruction selection.
4375 ShiftAmt = DAG.getNode(ISD::AND, SL, TargetType, TruncShiftAmt, ShiftMask);
4376 }
4377
4378 SDValue Lo = DAG.getNode(ISD::TRUNCATE, SL, TargetType, LHS);
4379 SDValue NewShift =
4380 DAG.getNode(ISD::SHL, SL, TargetType, Lo, ShiftAmt, N->getFlags());
4381
4382 const SDValue Zero = DAG.getConstant(0, SL, TargetScalarType);
4383 SDValue Vec;
4384
4385 if (VT.isVector()) {
4386 EVT ConcatType = TargetType.getDoubleNumVectorElementsVT(*DAG.getContext());
4387 unsigned NElts = TargetType.getVectorNumElements();
4389 SmallVector<SDValue, 16> HiAndLoOps(NElts * 2, Zero);
4390
4391 DAG.ExtractVectorElements(NewShift, HiOps, 0, NElts);
4392 for (unsigned I = 0; I != NElts; ++I)
4393 HiAndLoOps[2 * I + 1] = HiOps[I];
4394 Vec = DAG.getNode(ISD::BUILD_VECTOR, SL, ConcatType, HiAndLoOps);
4395 } else {
4396 EVT ConcatType = EVT::getVectorVT(*DAG.getContext(), TargetType, 2);
4397 Vec = DAG.getBuildVector(ConcatType, SL, {Zero, NewShift});
4398 }
4399 return DAG.getNode(ISD::BITCAST, SL, VT, Vec);
4400}
4401
4403 DAGCombinerInfo &DCI) const {
4404 SDValue RHS = N->getOperand(1);
4406 EVT VT = N->getValueType(0);
4407 SDValue LHS = N->getOperand(0);
4408 SelectionDAG &DAG = DCI.DAG;
4409 SDLoc SL(N);
4410
4411 if (VT.getScalarType() != MVT::i64)
4412 return SDValue();
4413
4414 // For C >= 32
4415 // i64 (sra x, C) -> (build_pair (sra hi_32(x), C - 32), sra hi_32(x), 31))
4416
4417 // On some subtargets, 64-bit shift is a quarter rate instruction. In the
4418 // common case, splitting this into a move and a 32-bit shift is faster and
4419 // the same code size.
4420 KnownBits Known = DAG.computeKnownBits(RHS);
4421
4422 EVT ElementType = VT.getScalarType();
4423 EVT TargetScalarType = ElementType.getHalfSizedIntegerVT(*DAG.getContext());
4424 EVT TargetType = VT.changeElementType(*DAG.getContext(), TargetScalarType);
4425
4426 if (Known.getMinValue().getZExtValue() < TargetScalarType.getSizeInBits())
4427 return SDValue();
4428
4429 SDValue ShiftFullAmt =
4430 DAG.getConstant(TargetScalarType.getSizeInBits() - 1, SL, TargetType);
4431 SDValue ShiftAmt;
4432 if (CRHS) {
4433 unsigned RHSVal = CRHS->getZExtValue();
4434 ShiftAmt = DAG.getConstant(RHSVal - TargetScalarType.getSizeInBits(), SL,
4435 TargetType);
4436 } else if (Known.getMinValue().getZExtValue() ==
4437 (ElementType.getSizeInBits() - 1)) {
4438 ShiftAmt = ShiftFullAmt;
4439 } else {
4440 SDValue TruncShiftAmt = DAG.getNode(ISD::TRUNCATE, SL, TargetType, RHS);
4441 const SDValue ShiftMask =
4442 DAG.getConstant(TargetScalarType.getSizeInBits() - 1, SL, TargetType);
4443 // This AND instruction will clamp out of bounds shift values.
4444 // It will also be removed during later instruction selection.
4445 ShiftAmt = DAG.getNode(ISD::AND, SL, TargetType, TruncShiftAmt, ShiftMask);
4446 }
4447
4448 EVT ConcatType;
4449 SDValue Hi;
4450 SDLoc LHSSL(LHS);
4451 // Bitcast LHS into ConcatType so hi-half of source can be extracted into Hi
4452 if (VT.isVector()) {
4453 unsigned NElts = TargetType.getVectorNumElements();
4454 ConcatType = TargetType.getDoubleNumVectorElementsVT(*DAG.getContext());
4455 SDValue SplitLHS = DAG.getNode(ISD::BITCAST, LHSSL, ConcatType, LHS);
4456 SmallVector<SDValue, 8> HiOps(NElts);
4457 SmallVector<SDValue, 16> HiAndLoOps;
4458
4459 DAG.ExtractVectorElements(SplitLHS, HiAndLoOps, 0, NElts * 2);
4460 for (unsigned I = 0; I != NElts; ++I) {
4461 HiOps[I] = HiAndLoOps[2 * I + 1];
4462 }
4463 Hi = DAG.getNode(ISD::BUILD_VECTOR, LHSSL, TargetType, HiOps);
4464 } else {
4465 const SDValue One = DAG.getConstant(1, LHSSL, TargetScalarType);
4466 ConcatType = EVT::getVectorVT(*DAG.getContext(), TargetType, 2);
4467 SDValue SplitLHS = DAG.getNode(ISD::BITCAST, LHSSL, ConcatType, LHS);
4468 Hi = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, LHSSL, TargetType, SplitLHS, One);
4469 }
4470
4471 KnownBits KnownLHS = DAG.computeKnownBits(LHS);
4472 SDValue NewShift, HiShift;
4473 if (KnownLHS.isNegative()) {
4474 HiShift = DAG.getAllOnesConstant(SL, TargetType);
4475 NewShift =
4476 DAG.getNode(ISD::SRA, SL, TargetType, Hi, ShiftAmt, N->getFlags());
4477 } else if (CRHS &&
4478 CRHS->getZExtValue() == (ElementType.getSizeInBits() - 1)) {
4479 NewShift = HiShift =
4480 DAG.getNode(ISD::SRA, SL, TargetType, Hi, ShiftAmt, N->getFlags());
4481 } else {
4482 Hi = DAG.getFreeze(Hi);
4483 HiShift = DAG.getNode(ISD::SRA, SL, TargetType, Hi, ShiftFullAmt);
4484 NewShift =
4485 DAG.getNode(ISD::SRA, SL, TargetType, Hi, ShiftAmt, N->getFlags());
4486 }
4487
4488 SDValue Vec;
4489 if (VT.isVector()) {
4490 unsigned NElts = TargetType.getVectorNumElements();
4493 SmallVector<SDValue, 16> HiAndLoOps(NElts * 2);
4494
4495 DAG.ExtractVectorElements(HiShift, HiOps, 0, NElts);
4496 DAG.ExtractVectorElements(NewShift, LoOps, 0, NElts);
4497 for (unsigned I = 0; I != NElts; ++I) {
4498 HiAndLoOps[2 * I + 1] = HiOps[I];
4499 HiAndLoOps[2 * I] = LoOps[I];
4500 }
4501 Vec = DAG.getNode(ISD::BUILD_VECTOR, SL, ConcatType, HiAndLoOps);
4502 } else {
4503 Vec = DAG.getBuildVector(ConcatType, SL, {NewShift, HiShift});
4504 }
4505 return DAG.getNode(ISD::BITCAST, SL, VT, Vec);
4506}
4507
4509 DAGCombinerInfo &DCI) const {
4510 SDValue RHS = N->getOperand(1);
4512 EVT VT = N->getValueType(0);
4513 SDValue LHS = N->getOperand(0);
4514 SelectionDAG &DAG = DCI.DAG;
4515 SDLoc SL(N);
4516 unsigned RHSVal;
4517
4518 if (CRHS) {
4519 RHSVal = CRHS->getZExtValue();
4520
4521 // fold (srl (and x, c1 << c2), c2) -> (and (srl(x, c2), c1)
4522 // this improves the ability to match BFE patterns in isel.
4523 if (LHS.getOpcode() == ISD::AND) {
4524 if (auto *Mask = dyn_cast<ConstantSDNode>(LHS.getOperand(1))) {
4525 unsigned MaskIdx, MaskLen;
4526 if (Mask->getAPIntValue().isShiftedMask(MaskIdx, MaskLen) &&
4527 MaskIdx == RHSVal) {
4528 return DAG.getNode(ISD::AND, SL, VT,
4529 DAG.getNode(ISD::SRL, SL, VT, LHS.getOperand(0),
4530 N->getOperand(1)),
4531 DAG.getNode(ISD::SRL, SL, VT, LHS.getOperand(1),
4532 N->getOperand(1)));
4533 }
4534 }
4535 }
4536 }
4537
4538 if (VT.getScalarType() != MVT::i64)
4539 return SDValue();
4540
4541 // for C >= 32
4542 // i64 (srl x, C) -> (build_pair (srl hi_32(x), C - 32), 0)
4543
4544 // On some subtargets, 64-bit shift is a quarter rate instruction. In the
4545 // common case, splitting this into a move and a 32-bit shift is faster and
4546 // the same code size.
4547 KnownBits Known = DAG.computeKnownBits(RHS);
4548
4549 EVT ElementType = VT.getScalarType();
4550 EVT TargetScalarType = ElementType.getHalfSizedIntegerVT(*DAG.getContext());
4551 EVT TargetType = VT.changeElementType(*DAG.getContext(), TargetScalarType);
4552
4553 if (Known.getMinValue().getZExtValue() < TargetScalarType.getSizeInBits())
4554 return SDValue();
4555
4556 SDValue ShiftAmt;
4557 if (CRHS) {
4558 ShiftAmt = DAG.getConstant(RHSVal - TargetScalarType.getSizeInBits(), SL,
4559 TargetType);
4560 } else {
4561 SDValue TruncShiftAmt = DAG.getNode(ISD::TRUNCATE, SL, TargetType, RHS);
4562 const SDValue ShiftMask =
4563 DAG.getConstant(TargetScalarType.getSizeInBits() - 1, SL, TargetType);
4564 // This AND instruction will clamp out of bounds shift values.
4565 // It will also be removed during later instruction selection.
4566 ShiftAmt = DAG.getNode(ISD::AND, SL, TargetType, TruncShiftAmt, ShiftMask);
4567 }
4568
4569 const SDValue Zero = DAG.getConstant(0, SL, TargetScalarType);
4570 EVT ConcatType;
4571 SDValue Hi;
4572 SDLoc LHSSL(LHS);
4573 // Bitcast LHS into ConcatType so hi-half of source can be extracted into Hi
4574 if (VT.isVector()) {
4575 unsigned NElts = TargetType.getVectorNumElements();
4576 ConcatType = TargetType.getDoubleNumVectorElementsVT(*DAG.getContext());
4577 SDValue SplitLHS = DAG.getNode(ISD::BITCAST, LHSSL, ConcatType, LHS);
4578 SmallVector<SDValue, 8> HiOps(NElts);
4579 SmallVector<SDValue, 16> HiAndLoOps;
4580
4581 DAG.ExtractVectorElements(SplitLHS, HiAndLoOps, /*Start=*/0, NElts * 2);
4582 for (unsigned I = 0; I != NElts; ++I)
4583 HiOps[I] = HiAndLoOps[2 * I + 1];
4584 Hi = DAG.getNode(ISD::BUILD_VECTOR, LHSSL, TargetType, HiOps);
4585 } else {
4586 const SDValue One = DAG.getConstant(1, LHSSL, TargetScalarType);
4587 ConcatType = EVT::getVectorVT(*DAG.getContext(), TargetType, 2);
4588 SDValue SplitLHS = DAG.getNode(ISD::BITCAST, LHSSL, ConcatType, LHS);
4589 Hi = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, LHSSL, TargetType, SplitLHS, One);
4590 }
4591
4592 SDValue NewShift =
4593 DAG.getNode(ISD::SRL, SL, TargetType, Hi, ShiftAmt, N->getFlags());
4594
4595 SDValue Vec;
4596 if (VT.isVector()) {
4597 unsigned NElts = TargetType.getVectorNumElements();
4599 SmallVector<SDValue, 16> HiAndLoOps(NElts * 2, Zero);
4600
4601 DAG.ExtractVectorElements(NewShift, LoOps, 0, NElts);
4602 for (unsigned I = 0; I != NElts; ++I)
4603 HiAndLoOps[2 * I] = LoOps[I];
4604 Vec = DAG.getNode(ISD::BUILD_VECTOR, SL, ConcatType, HiAndLoOps);
4605 } else {
4606 Vec = DAG.getBuildVector(ConcatType, SL, {NewShift, Zero});
4607 }
4608 return DAG.getNode(ISD::BITCAST, SL, VT, Vec);
4609}
4610
4612 SDNode *N, DAGCombinerInfo &DCI) const {
4613 SDLoc SL(N);
4614 SelectionDAG &DAG = DCI.DAG;
4615 EVT VT = N->getValueType(0);
4616 SDValue Src = N->getOperand(0);
4617
4618 // vt1 (truncate (bitcast (build_vector vt0:x, ...))) -> vt1 (bitcast vt0:x)
4619 if (Src.getOpcode() == ISD::BITCAST && !VT.isVector()) {
4620 SDValue Vec = Src.getOperand(0);
4621 if (Vec.getOpcode() == ISD::BUILD_VECTOR) {
4622 SDValue Elt0 = Vec.getOperand(0);
4623 EVT EltVT = Elt0.getValueType();
4624 if (VT.getFixedSizeInBits() <= EltVT.getFixedSizeInBits()) {
4625 if (EltVT.isFloatingPoint()) {
4626 Elt0 = DAG.getNode(ISD::BITCAST, SL,
4627 EltVT.changeTypeToInteger(), Elt0);
4628 }
4629
4630 return DAG.getNode(ISD::TRUNCATE, SL, VT, Elt0);
4631 }
4632 }
4633 }
4634
4635 // Equivalent of above for accessing the high element of a vector as an
4636 // integer operation.
4637 // trunc (srl (bitcast (build_vector x, y))), 16 -> trunc (bitcast y)
4638 if (Src.getOpcode() == ISD::SRL && !VT.isVector()) {
4639 if (auto *K = isConstOrConstSplat(Src.getOperand(1))) {
4640 SDValue BV = stripBitcast(Src.getOperand(0));
4641 if (BV.getOpcode() == ISD::BUILD_VECTOR) {
4642 EVT SrcEltVT = BV.getOperand(0).getValueType();
4643 unsigned SrcEltSize = SrcEltVT.getSizeInBits();
4644 unsigned BitIndex = K->getZExtValue();
4645 unsigned PartIndex = BitIndex / SrcEltSize;
4646
4647 if (PartIndex * SrcEltSize == BitIndex &&
4648 PartIndex < BV.getNumOperands()) {
4649 if (SrcEltVT.getSizeInBits() == VT.getSizeInBits()) {
4650 SDValue SrcElt =
4651 DAG.getNode(ISD::BITCAST, SL, SrcEltVT.changeTypeToInteger(),
4652 BV.getOperand(PartIndex));
4653 return DAG.getNode(ISD::TRUNCATE, SL, VT, SrcElt);
4654 }
4655 }
4656 }
4657 }
4658 }
4659
4660 // Partially shrink 64-bit shifts to 32-bit if reduced to 16-bit.
4661 //
4662 // i16 (trunc (srl i64:x, K)), K <= 16 ->
4663 // i16 (trunc (srl (i32 (trunc x), K)))
4664 if (VT.getScalarSizeInBits() < 32) {
4665 EVT SrcVT = Src.getValueType();
4666 if (SrcVT.getScalarSizeInBits() > 32 &&
4667 (Src.getOpcode() == ISD::SRL ||
4668 Src.getOpcode() == ISD::SRA ||
4669 Src.getOpcode() == ISD::SHL)) {
4670 SDValue Amt = Src.getOperand(1);
4671 KnownBits Known = DAG.computeKnownBits(Amt);
4672
4673 // - For left shifts, do the transform as long as the shift
4674 // amount is still legal for i32, so when ShiftAmt < 32 (<= 31)
4675 // - For right shift, do it if ShiftAmt <= (32 - Size) to avoid
4676 // losing information stored in the high bits when truncating.
4677 const unsigned MaxCstSize =
4678 (Src.getOpcode() == ISD::SHL) ? 31 : (32 - VT.getScalarSizeInBits());
4679 if (Known.getMaxValue().ule(MaxCstSize)) {
4680 EVT MidVT = VT.isVector() ?
4681 EVT::getVectorVT(*DAG.getContext(), MVT::i32,
4682 VT.getVectorNumElements()) : MVT::i32;
4683
4684 EVT NewShiftVT = getShiftAmountTy(MidVT, DAG.getDataLayout());
4685 SDValue Trunc = DAG.getNode(ISD::TRUNCATE, SL, MidVT,
4686 Src.getOperand(0));
4687 DCI.AddToWorklist(Trunc.getNode());
4688
4689 if (Amt.getValueType() != NewShiftVT) {
4690 Amt = DAG.getZExtOrTrunc(Amt, SL, NewShiftVT);
4691 DCI.AddToWorklist(Amt.getNode());
4692 }
4693
4694 SDValue ShrunkShift = DAG.getNode(Src.getOpcode(), SL, MidVT,
4695 Trunc, Amt);
4696 return DAG.getNode(ISD::TRUNCATE, SL, VT, ShrunkShift);
4697 }
4698 }
4699 }
4700
4701 return SDValue();
4702}
4703
4704// We need to specifically handle i64 mul here to avoid unnecessary conversion
4705// instructions. If we only match on the legalized i64 mul expansion,
4706// SimplifyDemandedBits will be unable to remove them because there will be
4707// multiple uses due to the separate mul + mulh[su].
4708static SDValue getMul24(SelectionDAG &DAG, const SDLoc &SL,
4709 SDValue N0, SDValue N1, unsigned Size, bool Signed) {
4710 if (Size <= 32) {
4711 unsigned MulOpc = Signed ? AMDGPUISD::MUL_I24 : AMDGPUISD::MUL_U24;
4712 return DAG.getNode(MulOpc, SL, MVT::i32, N0, N1);
4713 }
4714
4715 unsigned MulLoOpc = Signed ? AMDGPUISD::MUL_I24 : AMDGPUISD::MUL_U24;
4716 unsigned MulHiOpc = Signed ? AMDGPUISD::MULHI_I24 : AMDGPUISD::MULHI_U24;
4717
4718 SDValue MulLo = DAG.getNode(MulLoOpc, SL, MVT::i32, N0, N1);
4719 SDValue MulHi = DAG.getNode(MulHiOpc, SL, MVT::i32, N0, N1);
4720
4721 return DAG.getNode(ISD::BUILD_PAIR, SL, MVT::i64, MulLo, MulHi);
4722}
4723
4724/// If \p V is an add of a constant 1, returns the other operand. Otherwise
4725/// return SDValue().
4726static SDValue getAddOneOp(const SDNode *V) {
4727 if (V->getOpcode() != ISD::ADD)
4728 return SDValue();
4729
4730 return isOneConstant(V->getOperand(1)) ? V->getOperand(0) : SDValue();
4731}
4732
4734 DAGCombinerInfo &DCI) const {
4735 assert(N->getOpcode() == ISD::MUL);
4736 EVT VT = N->getValueType(0);
4737
4738 // Don't generate 24-bit multiplies on values that are in SGPRs, since
4739 // we only have a 32-bit scalar multiply (avoid values being moved to VGPRs
4740 // unnecessarily). isDivergent() is used as an approximation of whether the
4741 // value is in an SGPR.
4742 if (!N->isDivergent())
4743 return SDValue();
4744
4745 unsigned Size = VT.getSizeInBits();
4746 if (VT.isVector() || Size > 64)
4747 return SDValue();
4748
4749 SelectionDAG &DAG = DCI.DAG;
4750 SDLoc DL(N);
4751
4752 SDValue N0 = N->getOperand(0);
4753 SDValue N1 = N->getOperand(1);
4754
4755 // Undo InstCombine canonicalize X * (Y + 1) -> X * Y + X to enable mad
4756 // matching.
4757
4758 // mul x, (add y, 1) -> add (mul x, y), x
4759 auto IsFoldableAdd = [](SDValue V) -> SDValue {
4760 SDValue AddOp = getAddOneOp(V.getNode());
4761 if (!AddOp)
4762 return SDValue();
4763
4764 if (V.hasOneUse() || all_of(V->users(), [](const SDNode *U) -> bool {
4765 return U->getOpcode() == ISD::MUL;
4766 }))
4767 return AddOp;
4768
4769 return SDValue();
4770 };
4771
4772 // FIXME: The selection pattern is not properly checking for commuted
4773 // operands, so we have to place the mul in the LHS
4774 if (SDValue MulOper = IsFoldableAdd(N0)) {
4775 SDValue MulVal = DAG.getNode(N->getOpcode(), DL, VT, N1, MulOper);
4776 return DAG.getNode(ISD::ADD, DL, VT, MulVal, N1);
4777 }
4778
4779 if (SDValue MulOper = IsFoldableAdd(N1)) {
4780 SDValue MulVal = DAG.getNode(N->getOpcode(), DL, VT, N0, MulOper);
4781 return DAG.getNode(ISD::ADD, DL, VT, MulVal, N0);
4782 }
4783
4784 // There are i16 integer mul/mad.
4785 if (isTypeLegal(MVT::i16) && VT.getScalarType().bitsLE(MVT::i16))
4786 return SDValue();
4787
4788 // SimplifyDemandedBits has the annoying habit of turning useful zero_extends
4789 // in the source into any_extends if the result of the mul is truncated. Since
4790 // we can assume the high bits are whatever we want, use the underlying value
4791 // to avoid the unknown high bits from interfering.
4792 if (N0.getOpcode() == ISD::ANY_EXTEND)
4793 N0 = N0.getOperand(0);
4794
4795 if (N1.getOpcode() == ISD::ANY_EXTEND)
4796 N1 = N1.getOperand(0);
4797
4798 SDValue Mul;
4799
4800 if (Subtarget->hasMulU24() && isU24(N0, DAG) && isU24(N1, DAG)) {
4801 N0 = DAG.getZExtOrTrunc(N0, DL, MVT::i32);
4802 N1 = DAG.getZExtOrTrunc(N1, DL, MVT::i32);
4803 Mul = getMul24(DAG, DL, N0, N1, Size, false);
4804 } else if (Subtarget->hasMulI24() && isI24(N0, DAG) && isI24(N1, DAG)) {
4805 N0 = DAG.getSExtOrTrunc(N0, DL, MVT::i32);
4806 N1 = DAG.getSExtOrTrunc(N1, DL, MVT::i32);
4807 Mul = getMul24(DAG, DL, N0, N1, Size, true);
4808 } else {
4809 return SDValue();
4810 }
4811
4812 // We need to use sext even for MUL_U24, because MUL_U24 is used
4813 // for signed multiply of 8 and 16-bit types.
4814 return DAG.getSExtOrTrunc(Mul, DL, VT);
4815}
4816
4817SDValue
4819 DAGCombinerInfo &DCI) const {
4820 if (N->getValueType(0) != MVT::i32)
4821 return SDValue();
4822
4823 SelectionDAG &DAG = DCI.DAG;
4824 SDLoc DL(N);
4825
4826 bool Signed = N->getOpcode() == ISD::SMUL_LOHI;
4827 SDValue N0 = N->getOperand(0);
4828 SDValue N1 = N->getOperand(1);
4829
4830 // SimplifyDemandedBits has the annoying habit of turning useful zero_extends
4831 // in the source into any_extends if the result of the mul is truncated. Since
4832 // we can assume the high bits are whatever we want, use the underlying value
4833 // to avoid the unknown high bits from interfering.
4834 if (N0.getOpcode() == ISD::ANY_EXTEND)
4835 N0 = N0.getOperand(0);
4836 if (N1.getOpcode() == ISD::ANY_EXTEND)
4837 N1 = N1.getOperand(0);
4838
4839 // Try to use two fast 24-bit multiplies (one for each half of the result)
4840 // instead of one slow extending multiply.
4841 unsigned LoOpcode = 0;
4842 unsigned HiOpcode = 0;
4843 if (Signed) {
4844 if (Subtarget->hasMulI24() && isI24(N0, DAG) && isI24(N1, DAG)) {
4845 N0 = DAG.getSExtOrTrunc(N0, DL, MVT::i32);
4846 N1 = DAG.getSExtOrTrunc(N1, DL, MVT::i32);
4847 LoOpcode = AMDGPUISD::MUL_I24;
4848 HiOpcode = AMDGPUISD::MULHI_I24;
4849 }
4850 } else {
4851 if (Subtarget->hasMulU24() && isU24(N0, DAG) && isU24(N1, DAG)) {
4852 N0 = DAG.getZExtOrTrunc(N0, DL, MVT::i32);
4853 N1 = DAG.getZExtOrTrunc(N1, DL, MVT::i32);
4854 LoOpcode = AMDGPUISD::MUL_U24;
4855 HiOpcode = AMDGPUISD::MULHI_U24;
4856 }
4857 }
4858 if (!LoOpcode)
4859 return SDValue();
4860
4861 SDValue Lo = DAG.getNode(LoOpcode, DL, MVT::i32, N0, N1);
4862 SDValue Hi = DAG.getNode(HiOpcode, DL, MVT::i32, N0, N1);
4863 DCI.CombineTo(N, Lo, Hi);
4864 return SDValue(N, 0);
4865}
4866
4868 DAGCombinerInfo &DCI) const {
4869 EVT VT = N->getValueType(0);
4870
4871 if (!Subtarget->hasMulI24() || VT.isVector())
4872 return SDValue();
4873
4874 // Don't generate 24-bit multiplies on values that are in SGPRs, since
4875 // we only have a 32-bit scalar multiply (avoid values being moved to VGPRs
4876 // unnecessarily). isDivergent() is used as an approximation of whether the
4877 // value is in an SGPR.
4878 // This doesn't apply if no s_mul_hi is available (since we'll end up with a
4879 // valu op anyway)
4880 if (Subtarget->hasSMulHi() && !N->isDivergent())
4881 return SDValue();
4882
4883 SelectionDAG &DAG = DCI.DAG;
4884 SDLoc DL(N);
4885
4886 SDValue N0 = N->getOperand(0);
4887 SDValue N1 = N->getOperand(1);
4888
4889 if (!isI24(N0, DAG) || !isI24(N1, DAG))
4890 return SDValue();
4891
4892 N0 = DAG.getSExtOrTrunc(N0, DL, MVT::i32);
4893 N1 = DAG.getSExtOrTrunc(N1, DL, MVT::i32);
4894
4895 SDValue Mulhi = DAG.getNode(AMDGPUISD::MULHI_I24, DL, MVT::i32, N0, N1);
4896 DCI.AddToWorklist(Mulhi.getNode());
4897 return DAG.getSExtOrTrunc(Mulhi, DL, VT);
4898}
4899
4901 DAGCombinerInfo &DCI) const {
4902 EVT VT = N->getValueType(0);
4903
4904 if (VT.isVector() || VT.getSizeInBits() > 32 || !Subtarget->hasMulU24())
4905 return SDValue();
4906
4907 // Don't generate 24-bit multiplies on values that are in SGPRs, since
4908 // we only have a 32-bit scalar multiply (avoid values being moved to VGPRs
4909 // unnecessarily). isDivergent() is used as an approximation of whether the
4910 // value is in an SGPR.
4911 // This doesn't apply if no s_mul_hi is available (since we'll end up with a
4912 // valu op anyway)
4913 if (!N->isDivergent() && Subtarget->hasSMulHi())
4914 return SDValue();
4915
4916 SelectionDAG &DAG = DCI.DAG;
4917 SDLoc DL(N);
4918
4919 SDValue N0 = N->getOperand(0);
4920 SDValue N1 = N->getOperand(1);
4921
4922 if (!isU24(N0, DAG) || !isU24(N1, DAG))
4923 return SDValue();
4924
4925 N0 = DAG.getZExtOrTrunc(N0, DL, MVT::i32);
4926 N1 = DAG.getZExtOrTrunc(N1, DL, MVT::i32);
4927
4928 SDValue Mulhi = DAG.getNode(AMDGPUISD::MULHI_U24, DL, MVT::i32, N0, N1);
4929 DCI.AddToWorklist(Mulhi.getNode());
4930 return DAG.getZExtOrTrunc(Mulhi, DL, VT);
4931}
4932
4933SDValue AMDGPUTargetLowering::getFFBX_U32(SelectionDAG &DAG,
4934 SDValue Op,
4935 const SDLoc &DL,
4936 unsigned Opc) const {
4937 EVT VT = Op.getValueType();
4938 if (VT.bitsGT(MVT::i32))
4939 return SDValue();
4940
4941 if (VT != MVT::i32)
4942 Op = DAG.getNode(ISD::ZERO_EXTEND, DL, MVT::i32, Op);
4943
4944 SDValue FFBX = DAG.getNode(Opc, DL, MVT::i32, Op);
4945 if (VT != MVT::i32)
4946 FFBX = DAG.getNode(ISD::TRUNCATE, DL, VT, FFBX);
4947
4948 return FFBX;
4949}
4950
4951// The native instructions return -1 on 0 input. Optimize out a select that
4952// produces -1 on 0.
4953//
4954// TODO: If zero is not undef, we could also do this if the output is compared
4955// against the bitwidth.
4956//
4957// TODO: Should probably combine against FFBH_U32 instead of ctlz directly.
4959 SDValue LHS, SDValue RHS,
4960 DAGCombinerInfo &DCI) const {
4961 if (!isNullConstant(Cond.getOperand(1)))
4962 return SDValue();
4963
4964 SelectionDAG &DAG = DCI.DAG;
4965 ISD::CondCode CCOpcode = cast<CondCodeSDNode>(Cond.getOperand(2))->get();
4966 SDValue CmpLHS = Cond.getOperand(0);
4967
4968 // select (setcc x, 0, eq), -1, (ctlz_zero_poison x) -> ffbh_u32 x
4969 // select (setcc x, 0, eq), -1, (cttz_zero_poison x) -> ffbl_u32 x
4970 if (CCOpcode == ISD::SETEQ &&
4971 (isCtlzOpc(RHS.getOpcode()) || isCttzOpc(RHS.getOpcode())) &&
4972 RHS.getOperand(0) == CmpLHS && isAllOnesConstant(LHS)) {
4973 unsigned Opc =
4974 isCttzOpc(RHS.getOpcode()) ? AMDGPUISD::FFBL_B32 : AMDGPUISD::FFBH_U32;
4975 return getFFBX_U32(DAG, CmpLHS, SL, Opc);
4976 }
4977
4978 // select (setcc x, 0, ne), (ctlz_zero_poison x), -1 -> ffbh_u32 x
4979 // select (setcc x, 0, ne), (cttz_zero_poison x), -1 -> ffbl_u32 x
4980 if (CCOpcode == ISD::SETNE &&
4981 (isCtlzOpc(LHS.getOpcode()) || isCttzOpc(LHS.getOpcode())) &&
4982 LHS.getOperand(0) == CmpLHS && isAllOnesConstant(RHS)) {
4983 unsigned Opc =
4984 isCttzOpc(LHS.getOpcode()) ? AMDGPUISD::FFBL_B32 : AMDGPUISD::FFBH_U32;
4985
4986 return getFFBX_U32(DAG, CmpLHS, SL, Opc);
4987 }
4988
4989 return SDValue();
4990}
4991
4993 unsigned Op,
4994 const SDLoc &SL,
4995 SDValue Cond,
4996 SDValue N1,
4997 SDValue N2) {
4998 SelectionDAG &DAG = DCI.DAG;
4999 EVT VT = N1.getValueType();
5000
5001 SDValue NewSelect = DAG.getNode(ISD::SELECT, SL, VT, Cond,
5002 N1.getOperand(0), N2.getOperand(0));
5003 DCI.AddToWorklist(NewSelect.getNode());
5004 return DAG.getNode(Op, SL, VT, NewSelect);
5005}
5006
5007// Pull a free FP operation out of a select so it may fold into uses.
5008//
5009// select c, (fneg x), (fneg y) -> fneg (select c, x, y)
5010// select c, (fneg x), k -> fneg (select c, x, (fneg k))
5011//
5012// select c, (fabs x), (fabs y) -> fabs (select c, x, y)
5013// select c, (fabs x), +k -> fabs (select c, x, k)
5014SDValue
5016 SDValue N) const {
5017 SelectionDAG &DAG = DCI.DAG;
5018 SDValue Cond = N.getOperand(0);
5019 SDValue LHS = N.getOperand(1);
5020 SDValue RHS = N.getOperand(2);
5021
5022 EVT VT = N.getValueType();
5023 if ((LHS.getOpcode() == ISD::FABS && RHS.getOpcode() == ISD::FABS) ||
5024 (LHS.getOpcode() == ISD::FNEG && RHS.getOpcode() == ISD::FNEG)) {
5026 return SDValue();
5027
5028 return distributeOpThroughSelect(DCI, LHS.getOpcode(),
5029 SDLoc(N), Cond, LHS, RHS);
5030 }
5031
5032 bool Inv = false;
5033 if (RHS.getOpcode() == ISD::FABS || RHS.getOpcode() == ISD::FNEG) {
5034 std::swap(LHS, RHS);
5035 Inv = true;
5036 }
5037
5038 // TODO: Support vector constants.
5040 if ((LHS.getOpcode() == ISD::FNEG || LHS.getOpcode() == ISD::FABS) && CRHS &&
5041 !selectSupportsSourceMods(N.getNode())) {
5042 SDLoc SL(N);
5043 // If one side is an fneg/fabs and the other is a constant, we can push the
5044 // fneg/fabs down. If it's an fabs, the constant needs to be non-negative.
5045 SDValue NewLHS = LHS.getOperand(0);
5046 SDValue NewRHS = RHS;
5047
5048 // Careful: if the neg can be folded up, don't try to pull it back down.
5049 bool ShouldFoldNeg = true;
5050
5051 if (NewLHS.hasOneUse()) {
5052 unsigned Opc = NewLHS.getOpcode();
5053 if (LHS.getOpcode() == ISD::FNEG && fnegFoldsIntoOp(NewLHS.getNode()))
5054 ShouldFoldNeg = false;
5055 if (LHS.getOpcode() == ISD::FABS && Opc == ISD::FMUL)
5056 ShouldFoldNeg = false;
5057 }
5058
5059 if (ShouldFoldNeg) {
5060 if (LHS.getOpcode() == ISD::FABS && CRHS->isNegative())
5061 return SDValue();
5062
5063 // We're going to be forced to use a source modifier anyway, there's no
5064 // point to pulling the negate out unless we can get a size reduction by
5065 // negating the constant.
5066 //
5067 // TODO: Generalize to use getCheaperNegatedExpression which doesn't know
5068 // about cheaper constants.
5069 if (NewLHS.getOpcode() == ISD::FABS &&
5071 return SDValue();
5072
5074 return SDValue();
5075
5076 if (LHS.getOpcode() == ISD::FNEG)
5077 NewRHS = DAG.getNode(ISD::FNEG, SL, VT, RHS);
5078
5079 if (Inv)
5080 std::swap(NewLHS, NewRHS);
5081
5082 SDValue NewSelect = DAG.getNode(ISD::SELECT, SL, VT,
5083 Cond, NewLHS, NewRHS);
5084 DCI.AddToWorklist(NewSelect.getNode());
5085 return DAG.getNode(LHS.getOpcode(), SL, VT, NewSelect);
5086 }
5087 }
5088
5089 return SDValue();
5090}
5091
5093 DAGCombinerInfo &DCI) const {
5094 if (SDValue Folded = foldFreeOpFromSelect(DCI, SDValue(N, 0)))
5095 return Folded;
5096
5097 SDValue Cond = N->getOperand(0);
5098 if (Cond.getOpcode() != ISD::SETCC)
5099 return SDValue();
5100
5101 EVT VT = N->getValueType(0);
5102 SDValue LHS = Cond.getOperand(0);
5103 SDValue RHS = Cond.getOperand(1);
5104 SDValue CC = Cond.getOperand(2);
5105
5106 SDValue True = N->getOperand(1);
5107 SDValue False = N->getOperand(2);
5108
5109 if (Cond.hasOneUse()) { // TODO: Look for multiple select uses.
5110 SelectionDAG &DAG = DCI.DAG;
5111 if (DAG.isConstantValueOfAnyType(True) &&
5113 // Swap cmp + select pair to move constant to false input.
5114 // This will allow using VOPC cndmasks more often.
5115 // select (setcc x, y), k, x -> select (setccinv x, y), x, k
5116
5117 SDLoc SL(N);
5118 ISD::CondCode NewCC =
5119 getSetCCInverse(cast<CondCodeSDNode>(CC)->get(), LHS.getValueType());
5120
5121 SDValue NewCond = DAG.getSetCC(SL, Cond.getValueType(), LHS, RHS, NewCC);
5122 return DAG.getNode(ISD::SELECT, SL, VT, NewCond, False, True);
5123 }
5124
5125 if (VT == MVT::f32 && Subtarget->hasFminFmaxLegacy()) {
5126 SDValue MinMax = combineFMinMaxLegacy(SDLoc(N), VT, LHS, RHS, True, False,
5127 CC, N->getFlags(), DCI);
5128 // Revisit this node so we can catch min3/max3/med3 patterns.
5129 //DCI.AddToWorklist(MinMax.getNode());
5130 return MinMax;
5131 }
5132 }
5133
5134 // There's no reason to not do this if the condition has other uses.
5135 return performCtlz_CttzCombine(SDLoc(N), Cond, True, False, DCI);
5136}
5137
5138static bool isInv2Pi(const APFloat &APF) {
5139 static const APFloat KF16(APFloat::IEEEhalf(), APInt(16, 0x3118));
5140 static const APFloat KF32(APFloat::IEEEsingle(), APInt(32, 0x3e22f983));
5141 static const APFloat KF64(APFloat::IEEEdouble(), APInt(64, 0x3fc45f306dc9c882));
5142
5143 return APF.bitwiseIsEqual(KF16) ||
5144 APF.bitwiseIsEqual(KF32) ||
5145 APF.bitwiseIsEqual(KF64);
5146}
5147
5148// 0 and 1.0 / (0.5 * pi) do not have inline immmediates, so there is an
5149// additional cost to negate them.
5152 if (C->isZero())
5153 return C->isNegative() ? NegatibleCost::Cheaper : NegatibleCost::Expensive;
5154
5155 if (Subtarget->hasInv2PiInlineImm() && isInv2Pi(C->getValueAPF()))
5156 return C->isNegative() ? NegatibleCost::Cheaper : NegatibleCost::Expensive;
5157
5159}
5160
5166
5167static unsigned inverseMinMax(unsigned Opc) {
5168 switch (Opc) {
5169 case ISD::FMAXNUM:
5170 return ISD::FMINNUM;
5171 case ISD::FMINNUM:
5172 return ISD::FMAXNUM;
5173 case ISD::FMAXNUM_IEEE:
5174 return ISD::FMINNUM_IEEE;
5175 case ISD::FMINNUM_IEEE:
5176 return ISD::FMAXNUM_IEEE;
5177 case ISD::FMAXIMUM:
5178 return ISD::FMINIMUM;
5179 case ISD::FMINIMUM:
5180 return ISD::FMAXIMUM;
5181 case ISD::FMAXIMUMNUM:
5182 return ISD::FMINIMUMNUM;
5183 case ISD::FMINIMUMNUM:
5184 return ISD::FMAXIMUMNUM;
5185 case AMDGPUISD::FMAX_LEGACY:
5186 return AMDGPUISD::FMIN_LEGACY;
5187 case AMDGPUISD::FMIN_LEGACY:
5188 return AMDGPUISD::FMAX_LEGACY;
5189 default:
5190 llvm_unreachable("invalid min/max opcode");
5191 }
5192}
5193
5194/// \return true if it's profitable to try to push an fneg into its source
5195/// instruction.
5197 // If the input has multiple uses and we can either fold the negate down, or
5198 // the other uses cannot, give up. This both prevents unprofitable
5199 // transformations and infinite loops: we won't repeatedly try to fold around
5200 // a negate that has no 'good' form.
5201 if (N0.hasOneUse()) {
5202 // This may be able to fold into the source, but at a code size cost. Don't
5203 // fold if the fold into the user is free.
5204 if (allUsesHaveSourceMods(N, 0))
5205 return false;
5206 } else {
5207 if (fnegFoldsIntoOp(N0.getNode()) &&
5209 return false;
5210 }
5211
5212 return true;
5213}
5214
5216 DAGCombinerInfo &DCI) const {
5217 SelectionDAG &DAG = DCI.DAG;
5218 SDValue N0 = N->getOperand(0);
5219 EVT VT = N->getValueType(0);
5220
5221 unsigned Opc = N0.getOpcode();
5222
5223 if (!shouldFoldFNegIntoSrc(N, N0))
5224 return SDValue();
5225
5226 bool MayIgnoreSignedZeroForAllUses =
5227 N0->getFlags().hasNoSignedZeros() ||
5228 (N0.hasOneUse() && N->getFlags().hasNoSignedZeros());
5229
5230 SDLoc SL(N);
5231 switch (Opc) {
5232 case ISD::FADD: {
5233 if (!MayIgnoreSignedZeroForAllUses)
5234 return SDValue();
5235
5236 // (fneg (fadd x, y)) -> (fadd (fneg x), (fneg y))
5237 SDValue LHS = N0.getOperand(0);
5238 SDValue RHS = N0.getOperand(1);
5239
5240 if (LHS.getOpcode() != ISD::FNEG)
5241 LHS = DAG.getNode(ISD::FNEG, SL, VT, LHS);
5242 else
5243 LHS = LHS.getOperand(0);
5244
5245 if (RHS.getOpcode() != ISD::FNEG)
5246 RHS = DAG.getNode(ISD::FNEG, SL, VT, RHS);
5247 else
5248 RHS = RHS.getOperand(0);
5249
5250 SDValue Res = DAG.getNode(ISD::FADD, SL, VT, LHS, RHS, N0->getFlags());
5251 if (Res.getOpcode() != ISD::FADD)
5252 return SDValue(); // Op got folded away.
5253 if (!N0.hasOneUse())
5254 DAG.ReplaceAllUsesWith(N0, DAG.getNode(ISD::FNEG, SL, VT, Res));
5255 return Res;
5256 }
5257 case ISD::FMUL:
5258 case AMDGPUISD::FMUL_LEGACY: {
5259 // (fneg (fmul x, y)) -> (fmul x, (fneg y))
5260 // (fneg (fmul_legacy x, y)) -> (fmul_legacy x, (fneg y))
5261 SDValue LHS = N0.getOperand(0);
5262 SDValue RHS = N0.getOperand(1);
5263
5264 if (LHS.getOpcode() == ISD::FNEG)
5265 LHS = LHS.getOperand(0);
5266 else if (RHS.getOpcode() == ISD::FNEG)
5267 RHS = RHS.getOperand(0);
5268 else
5269 RHS = DAG.getNode(ISD::FNEG, SL, VT, RHS);
5270
5271 SDValue Res = DAG.getNode(Opc, SL, VT, LHS, RHS, N0->getFlags());
5272 if (Res.getOpcode() != Opc)
5273 return SDValue(); // Op got folded away.
5274 if (!N0.hasOneUse())
5275 DAG.ReplaceAllUsesWith(N0, DAG.getNode(ISD::FNEG, SL, VT, Res));
5276 return Res;
5277 }
5278 case ISD::FMA:
5279 case ISD::FMAD: {
5280 // TODO: handle llvm.amdgcn.fma.legacy
5281 if (!MayIgnoreSignedZeroForAllUses)
5282 return SDValue();
5283
5284 // (fneg (fma x, y, z)) -> (fma x, (fneg y), (fneg z))
5285 SDValue LHS = N0.getOperand(0);
5286 SDValue MHS = N0.getOperand(1);
5287 SDValue RHS = N0.getOperand(2);
5288
5289 if (LHS.getOpcode() == ISD::FNEG)
5290 LHS = LHS.getOperand(0);
5291 else if (MHS.getOpcode() == ISD::FNEG)
5292 MHS = MHS.getOperand(0);
5293 else
5294 MHS = DAG.getNode(ISD::FNEG, SL, VT, MHS);
5295
5296 if (RHS.getOpcode() != ISD::FNEG)
5297 RHS = DAG.getNode(ISD::FNEG, SL, VT, RHS);
5298 else
5299 RHS = RHS.getOperand(0);
5300
5301 SDValue Res = DAG.getNode(Opc, SL, VT, LHS, MHS, RHS);
5302 if (Res.getOpcode() != Opc)
5303 return SDValue(); // Op got folded away.
5304 if (!N0.hasOneUse())
5305 DAG.ReplaceAllUsesWith(N0, DAG.getNode(ISD::FNEG, SL, VT, Res));
5306 return Res;
5307 }
5308 case ISD::FMAXNUM:
5309 case ISD::FMINNUM:
5310 case ISD::FMAXNUM_IEEE:
5311 case ISD::FMINNUM_IEEE:
5312 case ISD::FMINIMUM:
5313 case ISD::FMAXIMUM:
5314 case ISD::FMINIMUMNUM:
5315 case ISD::FMAXIMUMNUM:
5316 case AMDGPUISD::FMAX_LEGACY:
5317 case AMDGPUISD::FMIN_LEGACY: {
5318 // fneg (fmaxnum x, y) -> fminnum (fneg x), (fneg y)
5319 // fneg (fminnum x, y) -> fmaxnum (fneg x), (fneg y)
5320 // fneg (fmax_legacy x, y) -> fmin_legacy (fneg x), (fneg y)
5321 // fneg (fmin_legacy x, y) -> fmax_legacy (fneg x), (fneg y)
5322
5323 SDValue LHS = N0.getOperand(0);
5324 SDValue RHS = N0.getOperand(1);
5325
5326 // 0 doesn't have a negated inline immediate.
5327 // TODO: This constant check should be generalized to other operations.
5329 return SDValue();
5330
5331 // Swapping min<->max flips which operand a signed zero tie selects.
5332 if ((Opc == AMDGPUISD::FMIN_LEGACY || Opc == AMDGPUISD::FMAX_LEGACY) &&
5333 !canIgnoreLegacyMinMaxTies(DAG, N0->getFlags(), LHS, RHS))
5334 return SDValue();
5335
5336 SDValue NegLHS = DAG.getNode(ISD::FNEG, SL, VT, LHS);
5337 SDValue NegRHS = DAG.getNode(ISD::FNEG, SL, VT, RHS);
5338 unsigned Opposite = inverseMinMax(Opc);
5339
5340 SDValue Res = DAG.getNode(Opposite, SL, VT, NegLHS, NegRHS, N0->getFlags());
5341 if (Res.getOpcode() != Opposite)
5342 return SDValue(); // Op got folded away.
5343 if (!N0.hasOneUse())
5344 DAG.ReplaceAllUsesWith(N0, DAG.getNode(ISD::FNEG, SL, VT, Res));
5345 return Res;
5346 }
5347 case AMDGPUISD::FMED3: {
5348 // med3 sorts a NaN input as smaller than everything regardless of its sign,
5349 // so negating all operands does not sign-flip the median when an input may
5350 // be NaN.
5351 if (!N0->getFlags().hasNoNaNs())
5352 return SDValue();
5353
5354 SDValue Ops[3];
5355 for (unsigned I = 0; I < 3; ++I)
5356 Ops[I] = DAG.getNode(ISD::FNEG, SL, VT, N0->getOperand(I), N0->getFlags());
5357
5358 SDValue Res = DAG.getNode(AMDGPUISD::FMED3, SL, VT, Ops, N0->getFlags());
5359 if (Res.getOpcode() != AMDGPUISD::FMED3)
5360 return SDValue(); // Op got folded away.
5361
5362 if (!N0.hasOneUse()) {
5363 SDValue Neg = DAG.getNode(ISD::FNEG, SL, VT, Res);
5364 DAG.ReplaceAllUsesWith(N0, Neg);
5365
5366 for (SDNode *U : Neg->users())
5367 DCI.AddToWorklist(U);
5368 }
5369
5370 return Res;
5371 }
5372 case ISD::FP_EXTEND:
5373 case ISD::FTRUNC:
5374 case ISD::FRINT:
5375 case ISD::FNEARBYINT: // XXX - Should fround be handled?
5376 case ISD::FROUNDEVEN:
5377 case ISD::FSIN:
5378 case ISD::FCANONICALIZE:
5379 case AMDGPUISD::RCP:
5380 case AMDGPUISD::RCP_LEGACY:
5381 case AMDGPUISD::RCP_IFLAG:
5382 case AMDGPUISD::SIN_HW: {
5383 SDValue CvtSrc = N0.getOperand(0);
5384 if (CvtSrc.getOpcode() == ISD::FNEG) {
5385 // (fneg (fp_extend (fneg x))) -> (fp_extend x)
5386 // (fneg (rcp (fneg x))) -> (rcp x)
5387 return DAG.getNode(Opc, SL, VT, CvtSrc.getOperand(0));
5388 }
5389
5390 if (!N0.hasOneUse())
5391 return SDValue();
5392
5393 // (fneg (fp_extend x)) -> (fp_extend (fneg x))
5394 // (fneg (rcp x)) -> (rcp (fneg x))
5395 SDValue Neg = DAG.getNode(ISD::FNEG, SL, CvtSrc.getValueType(), CvtSrc);
5396 return DAG.getNode(Opc, SL, VT, Neg, N0->getFlags());
5397 }
5398 case ISD::FP_ROUND: {
5399 SDValue CvtSrc = N0.getOperand(0);
5400
5401 if (CvtSrc.getOpcode() == ISD::FNEG) {
5402 // (fneg (fp_round (fneg x))) -> (fp_round x)
5403 return DAG.getNode(ISD::FP_ROUND, SL, VT,
5404 CvtSrc.getOperand(0), N0.getOperand(1));
5405 }
5406
5407 if (!N0.hasOneUse())
5408 return SDValue();
5409
5410 // (fneg (fp_round x)) -> (fp_round (fneg x))
5411 SDValue Neg = DAG.getNode(ISD::FNEG, SL, CvtSrc.getValueType(), CvtSrc);
5412 return DAG.getNode(ISD::FP_ROUND, SL, VT, Neg, N0.getOperand(1));
5413 }
5414 case ISD::FP16_TO_FP: {
5415 // v_cvt_f32_f16 supports source modifiers on pre-VI targets without legal
5416 // f16, but legalization of f16 fneg ends up pulling it out of the source.
5417 // Put the fneg back as a legal source operation that can be matched later.
5418 SDLoc SL(N);
5419
5420 SDValue Src = N0.getOperand(0);
5421 EVT SrcVT = Src.getValueType();
5422
5423 // fneg (fp16_to_fp x) -> fp16_to_fp (xor x, 0x8000)
5424 SDValue IntFNeg = DAG.getNode(ISD::XOR, SL, SrcVT, Src,
5425 DAG.getConstant(0x8000, SL, SrcVT));
5426 return DAG.getNode(ISD::FP16_TO_FP, SL, N->getValueType(0), IntFNeg);
5427 }
5428 case ISD::SELECT: {
5429 // fneg (select c, a, b) -> select c, (fneg a), (fneg b)
5430 // TODO: Invert conditions of foldFreeOpFromSelect
5431 return SDValue();
5432 }
5433 case ISD::BITCAST: {
5434 SDLoc SL(N);
5435 SDValue BCSrc = N0.getOperand(0);
5436 if (BCSrc.getOpcode() == ISD::BUILD_VECTOR) {
5437 SDValue HighBits = BCSrc.getOperand(BCSrc.getNumOperands() - 1);
5438 if (VT != MVT::f64 || HighBits.getValueType().getSizeInBits() != 32 ||
5439 !fnegFoldsIntoOp(HighBits.getNode()))
5440 return SDValue();
5441
5442 // f64 fneg only really needs to operate on the high half of of the
5443 // register, so try to force it to an f32 operation to help make use of
5444 // source modifiers.
5445 //
5446 //
5447 // fneg (f64 (bitcast (build_vector x, y))) ->
5448 // f64 (bitcast (build_vector (bitcast i32:x to f32),
5449 // (fneg (bitcast i32:y to f32)))
5450
5451 SDValue CastHi = DAG.getNode(ISD::BITCAST, SL, MVT::f32, HighBits);
5452 SDValue NegHi = DAG.getNode(ISD::FNEG, SL, MVT::f32, CastHi);
5453 SDValue CastBack =
5454 DAG.getNode(ISD::BITCAST, SL, HighBits.getValueType(), NegHi);
5455
5457 Ops.back() = CastBack;
5458 DCI.AddToWorklist(NegHi.getNode());
5459 SDValue Build =
5460 DAG.getNode(ISD::BUILD_VECTOR, SL, BCSrc.getValueType(), Ops);
5461 SDValue Result = DAG.getNode(ISD::BITCAST, SL, VT, Build);
5462
5463 if (!N0.hasOneUse())
5464 DAG.ReplaceAllUsesWith(N0, DAG.getNode(ISD::FNEG, SL, VT, Result));
5465 return Result;
5466 }
5467
5468 if (BCSrc.getOpcode() == ISD::SELECT && VT == MVT::f32 &&
5469 BCSrc.hasOneUse()) {
5470 // fneg (bitcast (f32 (select cond, i32:lhs, i32:rhs))) ->
5471 // select cond, (bitcast i32:lhs to f32), (bitcast i32:rhs to f32)
5472
5473 // TODO: Cast back result for multiple uses is beneficial in some cases.
5474
5475 SDValue LHS =
5476 DAG.getNode(ISD::BITCAST, SL, MVT::f32, BCSrc.getOperand(1));
5477 SDValue RHS =
5478 DAG.getNode(ISD::BITCAST, SL, MVT::f32, BCSrc.getOperand(2));
5479
5480 SDValue NegLHS = DAG.getNode(ISD::FNEG, SL, MVT::f32, LHS);
5481 SDValue NegRHS = DAG.getNode(ISD::FNEG, SL, MVT::f32, RHS);
5482
5483 return DAG.getNode(ISD::SELECT, SL, MVT::f32, BCSrc.getOperand(0), NegLHS,
5484 NegRHS);
5485 }
5486
5487 return SDValue();
5488 }
5489 default:
5490 return SDValue();
5491 }
5492}
5493
5495 DAGCombinerInfo &DCI) const {
5496 SelectionDAG &DAG = DCI.DAG;
5497 SDValue N0 = N->getOperand(0);
5498
5499 if (!N0.hasOneUse())
5500 return SDValue();
5501
5502 switch (N0.getOpcode()) {
5503 case ISD::FP16_TO_FP: {
5504 assert(!isTypeLegal(MVT::f16) && "should only see if f16 is illegal");
5505 SDLoc SL(N);
5506 SDValue Src = N0.getOperand(0);
5507 EVT SrcVT = Src.getValueType();
5508
5509 // fabs (fp16_to_fp x) -> fp16_to_fp (and x, 0x7fff)
5510 SDValue IntFAbs = DAG.getNode(ISD::AND, SL, SrcVT, Src,
5511 DAG.getConstant(0x7fff, SL, SrcVT));
5512 return DAG.getNode(ISD::FP16_TO_FP, SL, N->getValueType(0), IntFAbs);
5513 }
5514 case ISD::FP_ROUND: {
5515 SDLoc SL(N);
5516 SDValue CvtSrc = N0.getOperand(0);
5517
5518 // fabs (fp_round x) -> fp_round (fabs x)
5519 SDValue Abs = DAG.getNode(ISD::FABS, SL, CvtSrc.getValueType(), CvtSrc,
5520 N->getFlags());
5521 return DAG.getNode(ISD::FP_ROUND, SL, N->getValueType(0), Abs,
5522 N0.getOperand(1), N0->getFlags());
5523 }
5524 default:
5525 return SDValue();
5526 }
5527}
5528
5530 DAGCombinerInfo &DCI) const {
5531 const auto *CFP = dyn_cast<ConstantFPSDNode>(N->getOperand(0));
5532 if (!CFP)
5533 return SDValue();
5534
5535 std::optional<APFloat> Result = AMDGPU::evaluateRcp(CFP->getValueAPF());
5536 if (!Result)
5537 return SDValue();
5538
5539 return DCI.DAG.getConstantFP(*Result, SDLoc(N), N->getValueType(0));
5540}
5541
5543 if (!Subtarget->isGCN())
5544 return false;
5545
5548 auto &ST = DAG.getSubtarget<GCNSubtarget>();
5549 const auto *TII = ST.getInstrInfo();
5550
5551 if (!ST.hasVMovB64Inst() || (!SDConstant && !SDFPConstant))
5552 return false;
5553
5554 if (ST.has64BitLiterals())
5555 return true;
5556
5557 if (SDConstant) {
5558 const APInt &APVal = SDConstant->getAPIntValue();
5559 return isUInt<32>(APVal.getZExtValue()) || TII->isInlineConstant(APVal);
5560 }
5561
5562 APInt Val = SDFPConstant->getValueAPF().bitcastToAPInt();
5563 return isUInt<32>(Val.getZExtValue()) || TII->isInlineConstant(Val);
5564}
5565
5567 DAGCombinerInfo &DCI) const {
5568 SelectionDAG &DAG = DCI.DAG;
5569 SDLoc DL(N);
5570
5571 switch(N->getOpcode()) {
5572 default:
5573 break;
5574 case ISD::BITCAST: {
5575 EVT DestVT = N->getValueType(0);
5576
5577 // Push casts through vector builds. This helps avoid emitting a large
5578 // number of copies when materializing floating point vector constants.
5579 //
5580 // vNt1 bitcast (vNt0 (build_vector t0:x, t0:y)) =>
5581 // vnt1 = build_vector (t1 (bitcast t0:x)), (t1 (bitcast t0:y))
5582 if (DestVT.isVector()) {
5583 SDValue Src = N->getOperand(0);
5584 if (Src.getOpcode() == ISD::BUILD_VECTOR &&
5587 EVT SrcVT = Src.getValueType();
5588 unsigned NElts = DestVT.getVectorNumElements();
5589
5590 if (SrcVT.getVectorNumElements() == NElts) {
5591 EVT DestEltVT = DestVT.getVectorElementType();
5592
5593 SmallVector<SDValue, 8> CastedElts;
5594 SDLoc SL(N);
5595 for (unsigned I = 0, E = SrcVT.getVectorNumElements(); I != E; ++I) {
5596 SDValue Elt = Src.getOperand(I);
5597 CastedElts.push_back(DAG.getNode(ISD::BITCAST, DL, DestEltVT, Elt));
5598 }
5599
5600 return DAG.getBuildVector(DestVT, SL, CastedElts);
5601 }
5602 }
5603 }
5604
5605 if (DestVT.getSizeInBits() != 64 || !DestVT.isVector())
5606 break;
5607
5608 // Fold bitcasts of constants.
5609 //
5610 // v2i32 (bitcast i64:k) -> build_vector lo_32(k), hi_32(k)
5611 // TODO: Generalize and move to DAGCombiner
5612 SDValue Src = N->getOperand(0);
5614 SDLoc SL(N);
5615 if (isInt64ImmLegal(C, DAG))
5616 break;
5617 uint64_t CVal = C->getZExtValue();
5618 SDValue BV = DAG.getNode(ISD::BUILD_VECTOR, SL, MVT::v2i32,
5619 DAG.getConstant(Lo_32(CVal), SL, MVT::i32),
5620 DAG.getConstant(Hi_32(CVal), SL, MVT::i32));
5621 return DAG.getNode(ISD::BITCAST, SL, DestVT, BV);
5622 }
5623
5625 const APInt &Val = C->getValueAPF().bitcastToAPInt();
5626 SDLoc SL(N);
5627 if (isInt64ImmLegal(C, DAG))
5628 break;
5629 uint64_t CVal = Val.getZExtValue();
5630 SDValue Vec = DAG.getNode(ISD::BUILD_VECTOR, SL, MVT::v2i32,
5631 DAG.getConstant(Lo_32(CVal), SL, MVT::i32),
5632 DAG.getConstant(Hi_32(CVal), SL, MVT::i32));
5633
5634 return DAG.getNode(ISD::BITCAST, SL, DestVT, Vec);
5635 }
5636
5637 break;
5638 }
5639 case ISD::SHL:
5640 case ISD::SRA:
5641 case ISD::SRL: {
5642 // Range metadata can be invalidated when loads are converted to legal types
5643 // (e.g. v2i64 -> v4i32).
5644 // Try to convert vector shl/sra/srl before type legalization so that range
5645 // metadata can be utilized.
5646 if (!(N->getValueType(0).isVector() &&
5649 break;
5650 if (N->getOpcode() == ISD::SHL)
5651 return performShlCombine(N, DCI);
5652 if (N->getOpcode() == ISD::SRA)
5653 return performSraCombine(N, DCI);
5654 return performSrlCombine(N, DCI);
5655 }
5656 case ISD::TRUNCATE:
5657 return performTruncateCombine(N, DCI);
5658 case ISD::MUL:
5659 return performMulCombine(N, DCI);
5660 case AMDGPUISD::MUL_U24:
5661 case AMDGPUISD::MUL_I24: {
5662 if (SDValue Simplified = simplifyMul24(N, DCI))
5663 return Simplified;
5664 break;
5665 }
5666 case AMDGPUISD::MULHI_I24:
5667 case AMDGPUISD::MULHI_U24:
5668 return simplifyMul24(N, DCI);
5669 case ISD::SMUL_LOHI:
5670 case ISD::UMUL_LOHI:
5671 return performMulLoHiCombine(N, DCI);
5672 case ISD::MULHS:
5673 return performMulhsCombine(N, DCI);
5674 case ISD::MULHU:
5675 return performMulhuCombine(N, DCI);
5676 case ISD::SELECT:
5677 return performSelectCombine(N, DCI);
5678 case ISD::FNEG:
5679 return performFNegCombine(N, DCI);
5680 case ISD::FABS:
5681 return performFAbsCombine(N, DCI);
5682 case AMDGPUISD::BFE_I32:
5683 case AMDGPUISD::BFE_U32: {
5684 assert(N->getValueType(0) == MVT::i32 &&
5685 "BFE_I32/BFE_U32 is a 32-bit operation");
5686 ConstantSDNode *Width = dyn_cast<ConstantSDNode>(N->getOperand(2));
5687 if (!Width)
5688 break;
5689
5690 uint32_t WidthVal = Width->getZExtValue() & 0x1f;
5691 if (WidthVal == 0)
5692 return DAG.getConstant(0, DL, MVT::i32);
5693
5695 if (!Offset)
5696 break;
5697
5698 SDValue BitsFrom = N->getOperand(0);
5699 uint32_t OffsetVal = Offset->getZExtValue() & 0x1f;
5700
5701 bool Signed = N->getOpcode() == AMDGPUISD::BFE_I32;
5702
5703 if (OffsetVal == 0) {
5704 // This is already sign / zero extended, so try to fold away extra BFEs.
5705 EVT SmallVT = EVT::getIntegerVT(*DAG.getContext(), WidthVal);
5706 if (Signed) {
5707 if (DAG.ComputeNumSignBits(BitsFrom) >= 32 - WidthVal + 1)
5708 return BitsFrom;
5709
5710 // This is a sign_extend_inreg. Replace it to take advantage of existing
5711 // DAG Combines. If not eliminated, we will match back to BFE during
5712 // selection.
5713
5714 // TODO: The sext_inreg of extended types ends, although we can could
5715 // handle them in a single BFE.
5716 return DAG.getNode(ISD::SIGN_EXTEND_INREG, DL, MVT::i32, BitsFrom,
5717 DAG.getValueType(SmallVT));
5718 }
5719
5720 if (DAG.MaskedValueIsZero(BitsFrom,
5721 APInt::getHighBitsSet(32, 32 - WidthVal)))
5722 return BitsFrom;
5723
5724 return DAG.getZeroExtendInReg(BitsFrom, DL, SmallVT);
5725 }
5726
5727 if (ConstantSDNode *CVal = dyn_cast<ConstantSDNode>(BitsFrom)) {
5728 if (Signed) {
5729 return constantFoldBFE<int32_t>(DAG,
5730 CVal->getSExtValue(),
5731 OffsetVal,
5732 WidthVal,
5733 DL);
5734 }
5735
5736 return constantFoldBFE<uint32_t>(DAG,
5737 CVal->getZExtValue(),
5738 OffsetVal,
5739 WidthVal,
5740 DL);
5741 }
5742
5743 if ((OffsetVal + WidthVal) >= 32 &&
5744 !(OffsetVal == 16 && WidthVal == 16 && Subtarget->hasSDWA())) {
5745 SDValue ShiftVal = DAG.getConstant(OffsetVal, DL, MVT::i32);
5746 return DAG.getNode(Signed ? ISD::SRA : ISD::SRL, DL, MVT::i32,
5747 BitsFrom, ShiftVal);
5748 }
5749
5750 if (BitsFrom.hasOneUse()) {
5751 APInt Demanded = APInt::getBitsSet(32,
5752 OffsetVal,
5753 OffsetVal + WidthVal);
5754
5757 !DCI.isBeforeLegalizeOps());
5758 const TargetLowering &TLI = DAG.getTargetLoweringInfo();
5759 if (TLI.ShrinkDemandedConstant(BitsFrom, Demanded, TLO) ||
5760 TLI.SimplifyDemandedBits(BitsFrom, Demanded, Known, TLO)) {
5761 DCI.CommitTargetLoweringOpt(TLO);
5762 }
5763 }
5764
5765 break;
5766 }
5767 case ISD::LOAD:
5768 return performLoadCombine(N, DCI);
5769 case ISD::STORE:
5770 return performStoreCombine(N, DCI);
5771 case AMDGPUISD::RCP:
5772 case AMDGPUISD::RCP_IFLAG:
5773 return performRcpCombine(N, DCI);
5774 case ISD::AssertZext:
5775 case ISD::AssertSext:
5776 return performAssertSZExtCombine(N, DCI);
5778 return performIntrinsicWOChainCombine(N, DCI);
5779 case AMDGPUISD::FMAD_FTZ: {
5780 SDValue N0 = N->getOperand(0);
5781 SDValue N1 = N->getOperand(1);
5782 SDValue N2 = N->getOperand(2);
5783 EVT VT = N->getValueType(0);
5784
5785 // FMAD_FTZ is a FMAD + flush denormals to zero.
5786 // We flush the inputs, the intermediate step, and the output.
5790 if (N0CFP && N1CFP && N2CFP) {
5791 const auto FTZ = [](const APFloat &V) {
5792 if (V.isDenormal()) {
5793 APFloat Zero(V.getSemantics(), 0);
5794 return V.isNegative() ? -Zero : Zero;
5795 }
5796 return V;
5797 };
5798
5799 APFloat V0 = FTZ(N0CFP->getValueAPF());
5800 APFloat V1 = FTZ(N1CFP->getValueAPF());
5801 APFloat V2 = FTZ(N2CFP->getValueAPF());
5802 V0.multiply(V1, APFloat::rmNearestTiesToEven);
5803 V0 = FTZ(V0);
5804 V0.add(V2, APFloat::rmNearestTiesToEven);
5805 return DAG.getConstantFP(FTZ(V0), DL, VT);
5806 }
5807 break;
5808 }
5809 }
5810 return SDValue();
5811}
5812
5814 SDValue Op, const APInt &OriginalDemandedBits,
5815 const APInt &OriginalDemandedElts, KnownBits &Known, TargetLoweringOpt &TLO,
5816 unsigned Depth) const {
5817 switch (Op.getOpcode()) {
5819 switch (Op.getConstantOperandVal(0)) {
5820 case Intrinsic::amdgcn_readfirstlane:
5821 case Intrinsic::amdgcn_readlane:
5822 case Intrinsic::amdgcn_wwm: {
5823 if (SimplifyDemandedBits(Op.getOperand(1), OriginalDemandedBits,
5824 OriginalDemandedElts, Known, TLO, Depth + 1))
5825 return true;
5826 break;
5827 }
5828 case Intrinsic::amdgcn_set_inactive:
5829 case Intrinsic::amdgcn_set_inactive_chain_arg: {
5830 // The result is operand 1 in active lanes and operand 2 in inactive
5831 // lanes, so the known bits are the intersection of both operands.
5832 KnownBits KnownValue, KnownInactive;
5833 if (SimplifyDemandedBits(Op.getOperand(1), OriginalDemandedBits,
5834 OriginalDemandedElts, KnownValue, TLO,
5835 Depth + 1))
5836 return true;
5837 if (SimplifyDemandedBits(Op.getOperand(2), OriginalDemandedBits,
5838 OriginalDemandedElts, KnownInactive, TLO,
5839 Depth + 1))
5840 return true;
5841 Known = KnownValue.intersectWith(KnownInactive);
5842 break;
5843 }
5844 default:
5845 break;
5846 }
5847 break;
5848 }
5849 default:
5850 break;
5851 }
5852
5853 return false;
5854}
5855
5856//===----------------------------------------------------------------------===//
5857// Helper functions
5858//===----------------------------------------------------------------------===//
5859
5861 const TargetRegisterClass *RC,
5862 Register Reg, EVT VT,
5863 const SDLoc &SL,
5864 bool RawReg) const {
5866 MachineRegisterInfo &MRI = MF.getRegInfo();
5867 Register VReg;
5868
5869 if (!MRI.isLiveIn(Reg)) {
5870 VReg = MRI.createVirtualRegister(RC);
5871 MRI.addLiveIn(Reg, VReg);
5872 } else {
5873 VReg = MRI.getLiveInVirtReg(Reg);
5874 }
5875
5876 if (RawReg)
5877 return DAG.getRegister(VReg, VT);
5878
5879 return DAG.getCopyFromReg(DAG.getEntryNode(), SL, VReg, VT);
5880}
5881
5882// This may be called multiple times, and nothing prevents creating multiple
5883// objects at the same offset. See if we already defined this object.
5885 int64_t Offset) {
5886 for (int I = MFI.getObjectIndexBegin(); I < 0; ++I) {
5887 if (MFI.getObjectOffset(I) == Offset) {
5888 assert(MFI.getObjectSize(I) == Size);
5889 return I;
5890 }
5891 }
5892
5893 return MFI.CreateFixedObject(Size, Offset, true);
5894}
5895
5897 EVT VT,
5898 const SDLoc &SL,
5899 int64_t Offset) const {
5901 MachineFrameInfo &MFI = MF.getFrameInfo();
5902 int FI = getOrCreateFixedStackObject(MFI, VT.getStoreSize(), Offset);
5903
5904 auto SrcPtrInfo = MachinePointerInfo::getStack(MF, Offset);
5905 SDValue Ptr = DAG.getFrameIndex(FI, MVT::i32);
5906
5907 return DAG.getLoad(VT, SL, DAG.getEntryNode(), Ptr, SrcPtrInfo, Align(4),
5910}
5911
5913 const SDLoc &SL,
5914 SDValue Chain,
5915 SDValue ArgVal,
5916 int64_t Offset) const {
5920
5921 SDValue Ptr = DAG.getConstant(Offset, SL, MVT::i32);
5922 // Stores to the argument stack area are relative to the stack pointer.
5923 SDValue SP =
5924 DAG.getCopyFromReg(Chain, SL, Info->getStackPtrOffsetReg(), MVT::i32);
5925 Ptr = DAG.getNode(ISD::ADD, SL, MVT::i32, SP, Ptr);
5926 SDValue Store = DAG.getStore(Chain, SL, ArgVal, Ptr, DstInfo, Align(4),
5928 return Store;
5929}
5930
5932 const TargetRegisterClass *RC,
5933 EVT VT, const SDLoc &SL,
5934 const ArgDescriptor &Arg) const {
5935 assert(Arg && "Attempting to load missing argument");
5936
5937 SDValue V = Arg.isRegister() ?
5938 CreateLiveInRegister(DAG, RC, Arg.getRegister(), VT, SL) :
5939 loadStackInputValue(DAG, VT, SL, Arg.getStackOffset());
5940
5941 if (!Arg.isMasked())
5942 return V;
5943
5944 unsigned Mask = Arg.getMask();
5945 unsigned Shift = llvm::countr_zero<unsigned>(Mask);
5946 V = DAG.getNode(ISD::SRL, SL, VT, V,
5947 DAG.getShiftAmountConstant(Shift, VT, SL));
5948 return DAG.getNode(ISD::AND, SL, VT, V,
5949 DAG.getConstant(Mask >> Shift, SL, VT));
5950}
5951
5953 uint64_t ExplicitKernArgSize, const ImplicitParameter Param) const {
5954 unsigned ExplicitArgOffset = Subtarget->getExplicitKernelArgOffset();
5955 const Align Alignment = Subtarget->getAlignmentForImplicitArgPtr();
5956 uint64_t ArgOffset =
5957 alignTo(ExplicitKernArgSize, Alignment) + ExplicitArgOffset;
5958 switch (Param) {
5959 case FIRST_IMPLICIT:
5960 return ArgOffset;
5961 case PRIVATE_BASE:
5963 case SHARED_BASE:
5964 return ArgOffset + AMDGPU::ImplicitArg::SHARED_BASE_OFFSET;
5965 case QUEUE_PTR:
5966 return ArgOffset + AMDGPU::ImplicitArg::QUEUE_PTR_OFFSET;
5967 }
5968 llvm_unreachable("unexpected implicit parameter type");
5969}
5970
5977
5979 SelectionDAG &DAG, int Enabled,
5980 int &RefinementSteps,
5981 bool &UseOneConstNR,
5982 bool Reciprocal) const {
5983 EVT VT = Operand.getValueType();
5984
5985 if (VT == MVT::f32) {
5986 RefinementSteps = 0;
5987 return DAG.getNode(AMDGPUISD::RSQ, SDLoc(Operand), VT, Operand);
5988 }
5989
5990 // TODO: There is also f64 rsq instruction, but the documentation is less
5991 // clear on its precision.
5992
5993 return SDValue();
5994}
5995
5997 SelectionDAG &DAG, int Enabled,
5998 int &RefinementSteps) const {
5999 EVT VT = Operand.getValueType();
6000
6001 if (VT == MVT::f32) {
6002 // Reciprocal, < 1 ulp error.
6003 //
6004 // This reciprocal approximation converges to < 0.5 ulp error with one
6005 // newton rhapson performed with two fused multiple adds (FMAs).
6006
6007 RefinementSteps = 0;
6008 return DAG.getNode(AMDGPUISD::RCP, SDLoc(Operand), VT, Operand);
6009 }
6010
6011 // TODO: There is also f64 rcp instruction, but the documentation is less
6012 // clear on its precision.
6013
6014 return SDValue();
6015}
6016
6017static unsigned workitemIntrinsicDim(unsigned ID) {
6018 switch (ID) {
6019 case Intrinsic::amdgcn_workitem_id_x:
6020 return 0;
6021 case Intrinsic::amdgcn_workitem_id_y:
6022 return 1;
6023 case Intrinsic::amdgcn_workitem_id_z:
6024 return 2;
6025 default:
6026 llvm_unreachable("not a workitem intrinsic");
6027 }
6028}
6029
6031 const SDValue Op, KnownBits &Known,
6032 const APInt &DemandedElts, const SelectionDAG &DAG, unsigned Depth) const {
6033
6034 Known.resetAll(); // Don't know anything.
6035
6036 unsigned Opc = Op.getOpcode();
6037
6038 switch (Opc) {
6039 default:
6040 break;
6041 case AMDGPUISD::CARRY:
6042 case AMDGPUISD::BORROW: {
6043 Known.Zero = APInt::getHighBitsSet(32, 31);
6044 break;
6045 }
6046
6047 case AMDGPUISD::BFE_I32:
6048 case AMDGPUISD::BFE_U32: {
6049 ConstantSDNode *CWidth = dyn_cast<ConstantSDNode>(Op.getOperand(2));
6050 if (!CWidth)
6051 return;
6052
6053 uint32_t Width = CWidth->getZExtValue() & 0x1f;
6054
6055 if (Opc == AMDGPUISD::BFE_U32)
6056 Known.Zero = APInt::getHighBitsSet(32, 32 - Width);
6057
6058 break;
6059 }
6060 case AMDGPUISD::FP_TO_FP16: {
6061 unsigned BitWidth = Known.getBitWidth();
6062
6063 // High bits are zero.
6065 break;
6066 }
6067 case AMDGPUISD::MUL_U24:
6068 case AMDGPUISD::MUL_I24: {
6069 KnownBits LHSKnown = DAG.computeKnownBits(Op.getOperand(0), Depth + 1);
6070 KnownBits RHSKnown = DAG.computeKnownBits(Op.getOperand(1), Depth + 1);
6071 unsigned BitWidth = Op.getScalarValueSizeInBits();
6072
6073 // Sign/Zero extend from 24 bits.
6074 if (Opc == AMDGPUISD::MUL_I24) {
6075 LHSKnown = LHSKnown.trunc(24).sext(BitWidth);
6076 RHSKnown = RHSKnown.trunc(24).sext(BitWidth);
6077 } else {
6078 LHSKnown = LHSKnown.trunc(24).zext(BitWidth);
6079 RHSKnown = RHSKnown.trunc(24).zext(BitWidth);
6080 }
6081
6082 // TODO: SelfMultiply can be poison, but not undef.
6083 bool SelfMultiply = Op.getOperand(0) == Op.getOperand(1);
6084 if (SelfMultiply)
6085 SelfMultiply &= DAG.isGuaranteedNotToBeUndefOrPoison(
6086 Op.getOperand(0), DemandedElts, UndefPoisonKind::UndefOrPoison,
6087 Depth + 1);
6088
6089 Known = KnownBits::mul(LHSKnown, RHSKnown, SelfMultiply);
6090 break;
6091 }
6092 case AMDGPUISD::PERM: {
6093 ConstantSDNode *CMask = dyn_cast<ConstantSDNode>(Op.getOperand(2));
6094 if (!CMask)
6095 return;
6096
6097 KnownBits LHSKnown = DAG.computeKnownBits(Op.getOperand(0), Depth + 1);
6098 KnownBits RHSKnown = DAG.computeKnownBits(Op.getOperand(1), Depth + 1);
6099 unsigned Sel = CMask->getZExtValue();
6100
6101 for (unsigned I = 0; I < 32; I += 8) {
6102 unsigned SelBits = Sel & 0xff;
6103 if (SelBits < 4) {
6104 SelBits *= 8;
6105 Known.One |= ((RHSKnown.One.getZExtValue() >> SelBits) & 0xff) << I;
6106 Known.Zero |= ((RHSKnown.Zero.getZExtValue() >> SelBits) & 0xff) << I;
6107 } else if (SelBits < 7) {
6108 SelBits = (SelBits & 3) * 8;
6109 Known.One |= ((LHSKnown.One.getZExtValue() >> SelBits) & 0xff) << I;
6110 Known.Zero |= ((LHSKnown.Zero.getZExtValue() >> SelBits) & 0xff) << I;
6111 } else if (SelBits == 0x0c) {
6112 Known.Zero |= 0xFFull << I;
6113 } else if (SelBits > 0x0c) {
6114 Known.One |= 0xFFull << I;
6115 }
6116 Sel >>= 8;
6117 }
6118 break;
6119 }
6120 case AMDGPUISD::BUFFER_LOAD_UBYTE: {
6121 Known.Zero.setHighBits(24);
6122 break;
6123 }
6124 case AMDGPUISD::BUFFER_LOAD_USHORT: {
6125 Known.Zero.setHighBits(16);
6126 break;
6127 }
6128 case AMDGPUISD::LDS: {
6129 auto *GA = cast<GlobalAddressSDNode>(Op.getOperand(0).getNode());
6130 Align Alignment = GA->getGlobal()->getPointerAlignment(DAG.getDataLayout());
6131
6132 Known.Zero.setHighBits(16);
6133 Known.Zero.setLowBits(Log2(Alignment));
6134 break;
6135 }
6136 case AMDGPUISD::SMIN3:
6137 case AMDGPUISD::SMAX3:
6138 case AMDGPUISD::SMED3:
6139 case AMDGPUISD::UMIN3:
6140 case AMDGPUISD::UMAX3:
6141 case AMDGPUISD::UMED3: {
6142 KnownBits Known2 = DAG.computeKnownBits(Op.getOperand(2), Depth + 1);
6143 if (Known2.isUnknown())
6144 break;
6145
6146 KnownBits Known1 = DAG.computeKnownBits(Op.getOperand(1), Depth + 1);
6147 if (Known1.isUnknown())
6148 break;
6149
6150 KnownBits Known0 = DAG.computeKnownBits(Op.getOperand(0), Depth + 1);
6151 if (Known0.isUnknown())
6152 break;
6153
6154 // TODO: Handle LeadZero/LeadOne from UMIN/UMAX handling.
6155 Known.Zero = Known0.Zero & Known1.Zero & Known2.Zero;
6156 Known.One = Known0.One & Known1.One & Known2.One;
6157 break;
6158 }
6160 unsigned IID = Op.getConstantOperandVal(0);
6161 switch (IID) {
6162 case Intrinsic::amdgcn_workitem_id_x:
6163 case Intrinsic::amdgcn_workitem_id_y:
6164 case Intrinsic::amdgcn_workitem_id_z: {
6165 unsigned MaxValue = Subtarget->getMaxWorkitemID(
6167 Known.Zero.setHighBits(llvm::countl_zero(MaxValue));
6168 break;
6169 }
6170 case Intrinsic::amdgcn_readfirstlane:
6171 case Intrinsic::amdgcn_readlane:
6172 // Result is the data operand's value from some lane.
6173 Known = DAG.computeKnownBits(Op.getOperand(1), DemandedElts, Depth + 1);
6174 break;
6175 default:
6176 break;
6177 }
6178 }
6179 }
6180}
6181
6183 SDValue Op, const APInt &DemandedElts, const SelectionDAG &DAG,
6184 unsigned Depth) const {
6185 switch (Op.getOpcode()) {
6186 case AMDGPUISD::BFE_I32: {
6187 ConstantSDNode *Width = dyn_cast<ConstantSDNode>(Op.getOperand(2));
6188 if (!Width)
6189 return 1;
6190
6191 unsigned SignBits = 32 - (Width->getZExtValue() & 0x1f) + 1;
6192 if (!isNullConstant(Op.getOperand(1)))
6193 return SignBits;
6194
6195 // TODO: Could probably figure something out with non-0 offsets.
6196 unsigned Op0SignBits = DAG.ComputeNumSignBits(Op.getOperand(0), Depth + 1);
6197 return std::max(SignBits, Op0SignBits);
6198 }
6199
6200 case AMDGPUISD::BFE_U32: {
6201 ConstantSDNode *Width = dyn_cast<ConstantSDNode>(Op.getOperand(2));
6202 return Width ? 32 - (Width->getZExtValue() & 0x1f) : 1;
6203 }
6204
6205 case AMDGPUISD::CARRY:
6206 case AMDGPUISD::BORROW:
6207 return 31;
6208 case AMDGPUISD::BUFFER_LOAD_BYTE:
6209 return 25;
6210 case AMDGPUISD::BUFFER_LOAD_SHORT:
6211 return 17;
6212 case AMDGPUISD::BUFFER_LOAD_UBYTE:
6213 return 24;
6214 case AMDGPUISD::BUFFER_LOAD_USHORT:
6215 return 16;
6216 case AMDGPUISD::FP_TO_FP16:
6217 return 16;
6218 case AMDGPUISD::SMIN3:
6219 case AMDGPUISD::SMAX3:
6220 case AMDGPUISD::SMED3:
6221 case AMDGPUISD::UMIN3:
6222 case AMDGPUISD::UMAX3:
6223 case AMDGPUISD::UMED3: {
6224 unsigned Tmp2 = DAG.ComputeNumSignBits(Op.getOperand(2), Depth + 1);
6225 if (Tmp2 == 1)
6226 return 1; // Early out.
6227
6228 unsigned Tmp1 = DAG.ComputeNumSignBits(Op.getOperand(1), Depth + 1);
6229 if (Tmp1 == 1)
6230 return 1; // Early out.
6231
6232 unsigned Tmp0 = DAG.ComputeNumSignBits(Op.getOperand(0), Depth + 1);
6233 if (Tmp0 == 1)
6234 return 1; // Early out.
6235
6236 return std::min({Tmp0, Tmp1, Tmp2});
6237 }
6238 default:
6239 return 1;
6240 }
6241}
6242
6244 GISelValueTracking &Analysis, Register R, const APInt &DemandedElts,
6245 const MachineRegisterInfo &MRI, unsigned Depth) const {
6246 const MachineInstr *MI = MRI.getVRegDef(R);
6247 if (!MI)
6248 return 1;
6249
6250 // TODO: Check range metadata on MMO.
6251 switch (MI->getOpcode()) {
6252 case AMDGPU::G_AMDGPU_BUFFER_LOAD_SBYTE:
6253 return 25;
6254 case AMDGPU::G_AMDGPU_BUFFER_LOAD_SSHORT:
6255 return 17;
6256 case AMDGPU::G_AMDGPU_BUFFER_LOAD_UBYTE:
6257 return 24;
6258 case AMDGPU::G_AMDGPU_BUFFER_LOAD_USHORT:
6259 return 16;
6260 case AMDGPU::G_AMDGPU_SMED3:
6261 case AMDGPU::G_AMDGPU_UMED3: {
6262 auto [Dst, Src0, Src1, Src2] = MI->getFirst4Regs();
6263 unsigned Tmp2 = Analysis.computeNumSignBits(Src2, DemandedElts, Depth + 1);
6264 if (Tmp2 == 1)
6265 return 1;
6266 unsigned Tmp1 = Analysis.computeNumSignBits(Src1, DemandedElts, Depth + 1);
6267 if (Tmp1 == 1)
6268 return 1;
6269 unsigned Tmp0 = Analysis.computeNumSignBits(Src0, DemandedElts, Depth + 1);
6270 if (Tmp0 == 1)
6271 return 1;
6272 return std::min({Tmp0, Tmp1, Tmp2});
6273 }
6274 default:
6275 return 1;
6276 }
6277}
6278
6280 SDValue Op, const APInt &DemandedElts, const SelectionDAG &DAG,
6281 UndefPoisonKind Kind, bool ConsiderFlags, unsigned Depth) const {
6282 unsigned Opcode = Op.getOpcode();
6283 switch (Opcode) {
6284 case AMDGPUISD::BFE_I32:
6285 case AMDGPUISD::BFE_U32:
6286 return false;
6287 }
6289 Op, DemandedElts, DAG, Kind, ConsiderFlags, Depth);
6290}
6291
6293 SDValue Op, const APInt &DemandedElts, const SelectionDAG &DAG, bool SNaN,
6294 unsigned Depth) const {
6295 unsigned Opcode = Op.getOpcode();
6296 switch (Opcode) {
6297 case AMDGPUISD::FMIN_LEGACY:
6298 case AMDGPUISD::FMAX_LEGACY:
6299 return DAG.isKnownNeverNaN(Op.getOperand(0), SNaN, Depth + 1) &&
6300 DAG.isKnownNeverNaN(Op.getOperand(1), SNaN, Depth + 1);
6301 case AMDGPUISD::FMUL_LEGACY:
6302 case AMDGPUISD::CVT_PKRTZ_F16_F32: {
6303 if (SNaN)
6304 return true;
6305 return DAG.isKnownNeverNaN(Op.getOperand(0), SNaN, Depth + 1) &&
6306 DAG.isKnownNeverNaN(Op.getOperand(1), SNaN, Depth + 1);
6307 }
6308 case AMDGPUISD::FMED3:
6309 case AMDGPUISD::FMIN3:
6310 case AMDGPUISD::FMAX3:
6311 case AMDGPUISD::FMINIMUM3:
6312 case AMDGPUISD::FMAXIMUM3:
6313 case AMDGPUISD::FMAD_FTZ: {
6314 if (SNaN)
6315 return true;
6316 return DAG.isKnownNeverNaN(Op.getOperand(0), SNaN, Depth + 1) &&
6317 DAG.isKnownNeverNaN(Op.getOperand(1), SNaN, Depth + 1) &&
6318 DAG.isKnownNeverNaN(Op.getOperand(2), SNaN, Depth + 1);
6319 }
6320 case AMDGPUISD::CVT_F32_UBYTE0:
6321 case AMDGPUISD::CVT_F32_UBYTE1:
6322 case AMDGPUISD::CVT_F32_UBYTE2:
6323 case AMDGPUISD::CVT_F32_UBYTE3:
6324 return true;
6325
6326 case AMDGPUISD::RCP:
6327 case AMDGPUISD::RSQ:
6328 case AMDGPUISD::RCP_LEGACY:
6329 case AMDGPUISD::RSQ_CLAMP: {
6330 if (SNaN)
6331 return true;
6332
6333 // TODO: Need is known positive check.
6334 return false;
6335 }
6336 case ISD::FLDEXP:
6337 case AMDGPUISD::FRACT: {
6338 if (SNaN)
6339 return true;
6340 return DAG.isKnownNeverNaN(Op.getOperand(0), SNaN, Depth + 1);
6341 }
6342 case AMDGPUISD::DIV_SCALE:
6343 case AMDGPUISD::DIV_FMAS:
6344 case AMDGPUISD::DIV_FIXUP:
6345 // TODO: Refine on operands.
6346 return SNaN;
6347 case AMDGPUISD::SIN_HW:
6348 case AMDGPUISD::COS_HW: {
6349 // TODO: Need check for infinity
6350 return SNaN;
6351 }
6353 unsigned IntrinsicID = Op.getConstantOperandVal(0);
6354 // TODO: Handle more intrinsics
6355 switch (IntrinsicID) {
6356 case Intrinsic::amdgcn_cubeid:
6357 case Intrinsic::amdgcn_cvt_off_f32_i4:
6358 return true;
6359
6360 case Intrinsic::amdgcn_frexp_mant: {
6361 if (SNaN)
6362 return true;
6363 return DAG.isKnownNeverNaN(Op.getOperand(1), SNaN, Depth + 1);
6364 }
6365 case Intrinsic::amdgcn_cvt_pkrtz: {
6366 if (SNaN)
6367 return true;
6368 return DAG.isKnownNeverNaN(Op.getOperand(1), SNaN, Depth + 1) &&
6369 DAG.isKnownNeverNaN(Op.getOperand(2), SNaN, Depth + 1);
6370 }
6371 case Intrinsic::amdgcn_rcp:
6372 case Intrinsic::amdgcn_rsq:
6373 case Intrinsic::amdgcn_rcp_legacy:
6374 case Intrinsic::amdgcn_rsq_legacy:
6375 case Intrinsic::amdgcn_rsq_clamp:
6376 case Intrinsic::amdgcn_tanh: {
6377 if (SNaN)
6378 return true;
6379
6380 // TODO: Need is known positive check.
6381 return false;
6382 }
6383 case Intrinsic::amdgcn_trig_preop:
6384 case Intrinsic::amdgcn_fdot2:
6385 // TODO: Refine on operand
6386 return SNaN;
6387 case Intrinsic::amdgcn_fma_legacy:
6388 if (SNaN)
6389 return true;
6390 return DAG.isKnownNeverNaN(Op.getOperand(1), SNaN, Depth + 1) &&
6391 DAG.isKnownNeverNaN(Op.getOperand(2), SNaN, Depth + 1) &&
6392 DAG.isKnownNeverNaN(Op.getOperand(3), SNaN, Depth + 1);
6393 default:
6394 return false;
6395 }
6396 }
6397 default:
6398 return false;
6399 }
6400}
6401
6403 Register N0, Register N1) const {
6404 return MRI.hasOneNonDBGUse(N0); // FIXME: handle regbanks
6405}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
AMDGPU address space definition.
static LLVM_READONLY bool hasSourceMods(const MachineInstr &MI)
static bool isInv2Pi(const APFloat &APF)
static LLVM_READONLY bool opMustUseVOP3Encoding(const MachineInstr &MI, const MachineRegisterInfo &MRI)
returns true if the operation will definitely need to use a 64-bit encoding, and thus will use a VOP3...
static unsigned inverseMinMax(unsigned Opc)
uint64_t Imm
static SDValue extractF64Exponent(SDValue Hi, const SDLoc &SL, SelectionDAG &DAG)
static unsigned workitemIntrinsicDim(unsigned ID)
static int getOrCreateFixedStackObject(MachineFrameInfo &MFI, unsigned Size, int64_t Offset)
static SDValue constantFoldBFE(SelectionDAG &DAG, IntTy Src0, uint32_t Offset, uint32_t Width, const SDLoc &DL)
static SDValue getMad(SelectionDAG &DAG, const SDLoc &SL, EVT VT, SDValue X, SDValue Y, SDValue C, SDNodeFlags Flags=SDNodeFlags())
static SDValue getAddOneOp(const SDNode *V)
If V is an add of a constant 1, returns the other operand.
static bool canIgnoreLegacyMinMaxTies(const SelectionDAG &DAG, SDNodeFlags Flags, SDValue LHS, SDValue RHS)
static LLVM_READONLY bool selectSupportsSourceMods(const SDNode *N)
Return true if v_cndmask_b32 will support fabs/fneg source modifiers for the type for ISD::SELECT.
static cl::opt< bool > AMDGPUBypassSlowDiv("amdgpu-bypass-slow-div", cl::desc("Skip 64-bit divide for dynamic 32-bit values"), cl::init(true))
static SDValue getMul24(SelectionDAG &DAG, const SDLoc &SL, SDValue N0, SDValue N1, unsigned Size, bool Signed)
static bool fnegFoldsIntoOp(const SDNode *N)
static bool isI24(SDValue Op, SelectionDAG &DAG)
static bool isCttzOpc(unsigned Opc)
static bool isU24(SDValue Op, SelectionDAG &DAG)
static bool valueIsKnownNeverF32Denorm(SDValue Src)
Return true if it's known that Src can never be an f32 denormal value.
static SDValue distributeOpThroughSelect(TargetLowering::DAGCombinerInfo &DCI, unsigned Op, const SDLoc &SL, SDValue Cond, SDValue N1, SDValue N2)
static SDValue peekFNeg(SDValue Val)
static SDValue simplifyMul24(SDNode *Node24, TargetLowering::DAGCombinerInfo &DCI)
static bool isCtlzOpc(unsigned Opc)
static LLVM_READNONE bool fnegFoldsIntoOpcode(unsigned Opc)
static bool hasVolatileUser(SDNode *Val)
Interface definition of the TargetLowering class that is common to all AMD GPUs.
Contains the definition of a TargetInstrInfo class that is common to all AMD GPUs.
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
Function Alias Analysis Results
#define X(NUM, ENUM, NAME)
Definition ELF.h:857
block Block Frequency Analysis
static GCRegistry::Add< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
#define LLVM_READNONE
Definition Compiler.h:327
#define LLVM_READONLY
Definition Compiler.h:334
Provides analysis for querying information about KnownBits during GISel passes.
const HexagonInstrInfo * TII
static MaybeAlign getAlign(Value *Ptr)
IRTranslator LLVM IR MI
const AbstractManglingParser< Derived, Alloc >::OperatorInfo AbstractManglingParser< Derived, Alloc >::Ops[]
#define F(x, y, z)
Definition MD5.cpp:54
#define I(x, y, z)
Definition MD5.cpp:57
#define G(x, y, z)
Definition MD5.cpp:55
#define T
#define P(N)
const SmallVectorImpl< MachineOperand > & Cond
#define CH(x, y, z)
Definition SHA256.cpp:34
Func MI getDebugLoc()))
static TableGen::Emitter::Opt Y("gen-skeleton-entry", EmitSkeleton, "Generate example skeleton entry")
TTI::PartialReductionExtendKind ExtendKind
Value * RHS
Value * LHS
BinaryOperator * Mul
static CCAssignFn * CCAssignFnForCall(CallingConv::ID CC, bool IsVarArg)
static CCAssignFn * CCAssignFnForReturn(CallingConv::ID CC, bool IsVarArg)
unsigned allocateBarrierGlobal(const DataLayout &DL, const GlobalVariable &GV)
static std::optional< uint32_t > get32BitAbsoluteAddress(const GlobalValue &GV, unsigned AS)
unsigned allocateLDSGlobal(const DataLayout &DL, const GlobalVariable &GV)
static unsigned numBitsSigned(SDValue Op, SelectionDAG &DAG)
unsigned ComputeNumSignBitsForTargetNode(SDValue Op, const APInt &DemandedElts, const SelectionDAG &DAG, unsigned Depth=0) const override
This method can be implemented by targets that want to expose additional information about sign bits ...
SDValue performMulhuCombine(SDNode *N, DAGCombinerInfo &DCI) const
EVT getTypeForExtReturn(LLVMContext &Context, EVT VT, ISD::NodeType ExtendKind) const override
Return the type that should be used to zero or sign extend a zeroext/signext integer return value.
SDValue SplitVectorLoad(SDValue Op, SelectionDAG &DAG) const
Split a vector load into 2 loads of half the vector.
SDValue LowerCONCAT_VECTORS(SDValue Op, SelectionDAG &DAG) const
SDValue performLoadCombine(SDNode *N, DAGCombinerInfo &DCI) const
void analyzeFormalArgumentsCompute(CCState &State, const SmallVectorImpl< ISD::InputArg > &Ins) const
The SelectionDAGBuilder will automatically promote function arguments with illegal types.
SDValue LowerF64ToF16Safe(SDValue Src, const SDLoc &DL, SelectionDAG &DAG) const
SDValue LowerFROUND(SDValue Op, SelectionDAG &DAG) const
SDValue storeStackInputValue(SelectionDAG &DAG, const SDLoc &SL, SDValue Chain, SDValue ArgVal, int64_t Offset) const
bool storeOfVectorConstantIsCheap(bool IsZero, EVT MemVT, unsigned NumElem, unsigned AS) const override
Return true if it is expected to be cheaper to do a store of vector constant with the given size and ...
SDValue LowerEXTRACT_SUBVECTOR(SDValue Op, SelectionDAG &DAG) const
void computeKnownBitsForTargetNode(const SDValue Op, KnownBits &Known, const APInt &DemandedElts, const SelectionDAG &DAG, unsigned Depth=0) const override
Determine which of the bits specified in Mask are known to be either zero or one and return them in t...
bool shouldCombineMemoryType(EVT VT) const
SDValue splitBinaryBitConstantOpImpl(DAGCombinerInfo &DCI, const SDLoc &SL, unsigned Opc, SDValue LHS, uint32_t ValLo, uint32_t ValHi) const
Split the 64-bit value LHS into two 32-bit components, and perform the binary operation Opc to it wit...
SDValue lowerUnhandledCall(CallLoweringInfo &CLI, SmallVectorImpl< SDValue > &InVals, StringRef Reason) const
virtual SDValue LowerGlobalAddress(AMDGPUMachineFunctionInfo *MFI, SDValue Op, SelectionDAG &DAG) const
SDValue performAssertSZExtCombine(SDNode *N, DAGCombinerInfo &DCI) const
bool isTruncateFree(EVT Src, EVT Dest) const override
bool aggressivelyPreferBuildVectorSources(EVT VecVT) const override
SDValue LowerFCEIL(SDValue Op, SelectionDAG &DAG) const
TargetLowering::NegatibleCost getConstantNegateCost(const ConstantFPSDNode *C) const
SDValue LowerFLOGUnsafe(SDValue Op, const SDLoc &SL, SelectionDAG &DAG, bool IsLog10, SDNodeFlags Flags) const
SDValue combineFMinMaxLegacy(const SDLoc &DL, EVT VT, SDValue LHS, SDValue RHS, SDValue True, SDValue False, SDValue CC, SDNodeFlags Flags, DAGCombinerInfo &DCI) const
Flags must be the select flags, not the compare (SELECT_CC flags come from the fcmp and say nothing a...
SDValue performMulhsCombine(SDNode *N, DAGCombinerInfo &DCI) const
SDValue lowerFEXPUnsafeImpl(SDValue Op, const SDLoc &SL, SelectionDAG &DAG, SDNodeFlags Flags, bool IsExp10) const
bool isSDNodeAlwaysUniform(const SDNode *N) const override
bool isDesirableToCommuteWithShift(const SDNode *N, CombineLevel Level) const override
Return true if it is profitable to move this shift by a constant amount through its operand,...
SDValue performShlCombine(SDNode *N, DAGCombinerInfo &DCI) const
bool isCheapToSpeculateCtlz(Type *Ty) const override
Return true if it is cheap to speculate a call to intrinsic ctlz.
SDValue LowerSDIVREM(SDValue Op, SelectionDAG &DAG) const
bool isFNegFree(EVT VT) const override
Return true if an fneg operation is free to the point where it is never worthwhile to replace it with...
FPImmAction getFPImmAction(const APFloat &Imm, EVT VT, bool ForCodeSize) const override
Returns how the legalizer should materialize the specified FP immediate.
SDValue LowerINT_TO_FP64(SDValue Op, SelectionDAG &DAG, bool Signed) const
unsigned computeNumSignBitsForTargetInstr(GISelValueTracking &Analysis, Register R, const APInt &DemandedElts, const MachineRegisterInfo &MRI, unsigned Depth=0) const override
This method can be implemented by targets that want to expose additional information about sign bits ...
SDValue LowerOperation(SDValue Op, SelectionDAG &DAG) const override
This callback is invoked for operations that are unsupported by the target, which are registered to u...
SDValue LowerFP_TO_FP16(SDValue Op, SelectionDAG &DAG) const
SDValue addTokenForArgument(SDValue Chain, SelectionDAG &DAG, MachineFrameInfo &MFI, int ClobberedFI) const
bool isReassocProfitable(MachineRegisterInfo &MRI, Register N0, Register N1) const override
bool isKnownNeverNaNForTargetNode(SDValue Op, const APInt &DemandedElts, const SelectionDAG &DAG, bool SNaN=false, unsigned Depth=0) const override
If SNaN is false,.
static bool needsDenormHandlingF32(const SelectionDAG &DAG, SDValue Src, SDNodeFlags Flags)
SDValue lowerFPOW(SDValue Op, SelectionDAG &DAG) const
uint32_t getImplicitParameterOffset(const MachineFunction &MF, const ImplicitParameter Param) const
Helper function that returns the byte offset of the given type of implicit parameter.
SDValue lowerFEXPF64(SDValue Op, SelectionDAG &DAG) const
SDValue LowerFFLOOR(SDValue Op, SelectionDAG &DAG) const
SDValue performSelectCombine(SDNode *N, DAGCombinerInfo &DCI) const
SDValue performFNegCombine(SDNode *N, DAGCombinerInfo &DCI) const
SDValue LowerFP_TO_INT(SDValue Op, SelectionDAG &DAG) const
bool isConstantCostlierToNegate(SDValue N) const
SDValue loadInputValue(SelectionDAG &DAG, const TargetRegisterClass *RC, EVT VT, const SDLoc &SL, const ArgDescriptor &Arg) const
SDValue lowerFEXP10Unsafe(SDValue Op, const SDLoc &SL, SelectionDAG &DAG, SDNodeFlags Flags) const
Emit approx-funcs appropriate lowering for exp10.
bool shouldReduceLoadWidth(SDNode *Load, ISD::LoadExtType ExtType, EVT ExtVT, std::optional< unsigned > ByteOffset) const override
Return true if it is profitable to reduce a load to a smaller type.
SDValue LowerUINT_TO_FP(SDValue Op, SelectionDAG &DAG) const
bool canCreateUndefOrPoisonForTargetNode(SDValue Op, const APInt &DemandedElts, const SelectionDAG &DAG, UndefPoisonKind Kind, bool ConsiderFlags, unsigned Depth) const override
Return true if Op can create undef or poison from non-undef & non-poison operands.
bool isCheapToSpeculateCttz(Type *Ty) const override
Return true if it is cheap to speculate a call to intrinsic cttz.
SDValue performCtlz_CttzCombine(const SDLoc &SL, SDValue Cond, SDValue LHS, SDValue RHS, DAGCombinerInfo &DCI) const
SDValue performSraCombine(SDNode *N, DAGCombinerInfo &DCI) const
bool isSelectSupported(SelectSupportKind) const override
bool isZExtFree(Type *Src, Type *Dest) const override
Return true if any actual instruction that defines a value of type FromTy implicitly zero-extends the...
SDValue lowerFEXP2(SDValue Op, SelectionDAG &DAG) const
SDValue LowerCall(CallLoweringInfo &CLI, SmallVectorImpl< SDValue > &InVals) const override
This hook must be implemented to lower calls into the specified DAG.
SDValue performSrlCombine(SDNode *N, DAGCombinerInfo &DCI) const
SDValue lowerFEXP(SDValue Op, SelectionDAG &DAG) const
SDValue getIsFinite(SelectionDAG &DAG, SDValue Op, SDNodeFlags Flags) const
bool isLoadBitCastBeneficial(EVT, EVT, const SelectionDAG &DAG, const MachineMemOperand &MMO) const final
Return true if the following transform is beneficial: fold (conv (load x)) -> (load (conv*)x) On arch...
std::pair< SDValue, SDValue > splitVector(const SDValue &N, const SDLoc &DL, const EVT &LoVT, const EVT &HighVT, SelectionDAG &DAG) const
Split a vector value into two parts of types LoVT and HiVT.
AMDGPUTargetLowering(const TargetMachine &TM, const TargetSubtargetInfo &STI, const AMDGPUSubtarget &AMDGPUSTI)
SDValue LowerFLOGCommon(SDValue Op, SelectionDAG &DAG) const
SDValue foldFreeOpFromSelect(TargetLowering::DAGCombinerInfo &DCI, SDValue N) const
SDValue LowerINT_TO_FP32(SDValue Op, SelectionDAG &DAG, bool Signed) const
bool isFAbsFree(EVT VT) const override
Return true if an fabs operation is free to the point where it is never worthwhile to replace it with...
bool isInt64ImmLegal(SDNode *Val, SelectionDAG &DAG) const
Check whether value Val can be supported by v_mov_b64, for the current target.
SDValue loadStackInputValue(SelectionDAG &DAG, EVT VT, const SDLoc &SL, int64_t Offset) const
Similar to CreateLiveInRegister, except value maybe loaded from a stack slot rather than passed in a ...
SDValue LowerFLOG2(SDValue Op, SelectionDAG &DAG) const
static EVT getEquivalentMemType(LLVMContext &Context, EVT VT)
SDValue LowerCTLS(SDValue Op, SelectionDAG &DAG) const
Split a vector store into multiple scalar stores.
SDValue getSqrtEstimate(SDValue Operand, SelectionDAG &DAG, int Enabled, int &RefinementSteps, bool &UseOneConstNR, bool Reciprocal) const override
Hooks for building estimates in place of slower divisions and square roots.
SDValue performTruncateCombine(SDNode *N, DAGCombinerInfo &DCI) const
SDValue LowerSINT_TO_FP(SDValue Op, SelectionDAG &DAG) const
static SDValue stripBitcast(SDValue Val)
SDValue LowerBlockAddress(SDValue Op, SelectionDAG &DAG) const
SDValue CreateLiveInRegister(SelectionDAG &DAG, const TargetRegisterClass *RC, Register Reg, EVT VT, const SDLoc &SL, bool RawReg=false) const
Helper function that adds Reg to the LiveIn list of the DAG's MachineFunction.
SDValue SplitVectorStore(SDValue Op, SelectionDAG &DAG) const
Split a vector store into 2 stores of half the vector.
SDValue LowerCTLZ_CTTZ(SDValue Op, SelectionDAG &DAG) const
SDValue getNegatedExpression(SDValue Op, SelectionDAG &DAG, bool LegalOperations, bool ForCodeSize, NegatibleCost &Cost, unsigned Depth) const override
Return the newly negated expression if the cost is not expensive and set the cost in Cost to indicate...
std::pair< SDValue, SDValue > split64BitValue(SDValue Op, SelectionDAG &DAG) const
Return 64-bit value Op as two 32-bit integers.
SDValue performMulCombine(SDNode *N, DAGCombinerInfo &DCI) const
SDValue combineFMinMaxLegacyImpl(const SDLoc &DL, EVT VT, SDValue LHS, SDValue RHS, SDValue True, SDValue False, SDValue CC, SDNodeFlags Flags, DAGCombinerInfo &DCI) const
SDValue getRecipEstimate(SDValue Operand, SelectionDAG &DAG, int Enabled, int &RefinementSteps) const override
Return a reciprocal estimate value for the input operand.
SDValue LowerFNEARBYINT(SDValue Op, SelectionDAG &DAG) const
SDValue LowerSIGN_EXTEND_INREG(SDValue Op, SelectionDAG &DAG) const
static CCAssignFn * CCAssignFnForReturn(CallingConv::ID CC, bool IsVarArg)
std::pair< SDValue, SDValue > getScaledLogInput(SelectionDAG &DAG, const SDLoc SL, SDValue Op, SDNodeFlags Flags) const
If denormal handling is required return the scaled input to FLOG2, and the check for denormal range.
static CCAssignFn * CCAssignFnForCall(CallingConv::ID CC, bool IsVarArg)
Selects the correct CCAssignFn for a given CallingConvention value.
bool SimplifyDemandedBitsForTargetNode(SDValue Op, const APInt &OriginalDemandedBits, const APInt &OriginalDemandedElts, KnownBits &Known, TargetLoweringOpt &TLO, unsigned Depth) const override
Attempt to simplify any target nodes based on the demanded bits/elts, returning true on success.
static bool allUsesHaveSourceMods(const SDNode *N, unsigned CostThreshold=4)
SDValue LowerFROUNDEVEN(SDValue Op, SelectionDAG &DAG) const
static unsigned numBitsUnsigned(SDValue Op, SelectionDAG &DAG)
SDValue lowerFEXPUnsafe(SDValue Op, const SDLoc &SL, SelectionDAG &DAG, SDNodeFlags Flags) const
SDValue LowerFTRUNC(SDValue Op, SelectionDAG &DAG) const
SDValue LowerDYNAMIC_STACKALLOC(SDValue Op, SelectionDAG &DAG) const
static bool allowApproxFunc(const SelectionDAG &DAG, SDNodeFlags Flags)
bool ShouldShrinkFPConstant(EVT VT) const override
If true, then instruction selection should seek to shrink the FP constant of the specified type to a ...
SDValue LowerReturn(SDValue Chain, CallingConv::ID CallConv, bool isVarArg, const SmallVectorImpl< ISD::OutputArg > &Outs, const SmallVectorImpl< SDValue > &OutVals, const SDLoc &DL, SelectionDAG &DAG) const override
This hook must be implemented to lower outgoing return values, described by the Outs array,...
SDValue performStoreCombine(SDNode *N, DAGCombinerInfo &DCI) const
void ReplaceNodeResults(SDNode *N, SmallVectorImpl< SDValue > &Results, SelectionDAG &DAG) const override
This callback is invoked when a node result type is illegal for the target, and the operation was reg...
SDValue performRcpCombine(SDNode *N, DAGCombinerInfo &DCI) const
SDValue lowerCTLZResults(SDValue Op, SelectionDAG &DAG) const
SDValue LowerFP_TO_INT_SAT(SDValue Op, SelectionDAG &DAG) const
SDValue performFAbsCombine(SDNode *N, DAGCombinerInfo &DCI) const
SDValue LowerFP_TO_INT64(SDValue Op, SelectionDAG &DAG, bool Signed) const
static bool shouldFoldFNegIntoSrc(SDNode *FNeg, SDValue FNegSrc)
bool isNarrowingProfitable(SDNode *N, EVT SrcVT, EVT DestVT) const override
Return true if it's profitable to narrow operations of type SrcVT to DestVT.
SDValue LowerFRINT(SDValue Op, SelectionDAG &DAG) const
SDValue performIntrinsicWOChainCombine(SDNode *N, DAGCombinerInfo &DCI) const
SDValue LowerUDIVREM(SDValue Op, SelectionDAG &DAG) const
SDValue performMulLoHiCombine(SDNode *N, DAGCombinerInfo &DCI) const
SDValue PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const override
This method will be invoked for all target nodes and for any target-independent nodes that the target...
SDValue lowerINT_TO_FPImpl(SDValue Op, SelectionDAG &DAG, bool Signed) const
void LowerUDIVREM64(SDValue Op, SelectionDAG &DAG, SmallVectorImpl< SDValue > &Results) const
SDValue WidenOrSplitVectorLoad(SDValue Op, SelectionDAG &DAG) const
Widen a suitably aligned v3 load.
SDValue LowerDIVREMToFloat(SDValue Op, SelectionDAG &DAG, bool sign) const
std::pair< EVT, EVT > getSplitDestVTs(const EVT &VT, SelectionDAG &DAG) const
Split a vector type into two parts.
SDValue getHiHalf64(SDValue Op, SelectionDAG &DAG) const
SDValue LowerINT_TO_FP16(SDValue Op, SelectionDAG &DAG, EVT FP16Ty) const
unsigned getVectorIdxWidth(const DataLayout &) const override
Returns the type to be used for the index operand vector operations.
static const fltSemantics & IEEEsingle()
Definition APFloat.h:304
static const fltSemantics & IEEEdouble()
Definition APFloat.h:305
static constexpr roundingMode rmNearestTiesToEven
Definition APFloat.h:361
static const fltSemantics & IEEEhalf()
Definition APFloat.h:302
static APFloat getQNaN(const fltSemantics &Sem, bool Negative=false, const APInt *payload=nullptr)
Factory for QNaN values.
Definition APFloat.h:1224
bool bitwiseIsEqual(const APFloat &RHS) const
Definition APFloat.h:1548
static APFloat getSmallestNormalized(const fltSemantics &Sem, bool Negative=false)
Returns the smallest (by magnitude) normalized finite number in the given semantics.
Definition APFloat.h:1262
APInt bitcastToAPInt() const
Definition APFloat.h:1475
static APFloat getInf(const fltSemantics &Sem, bool Negative=false)
Factory for Positive and Negative Infinity.
Definition APFloat.h:1202
Class for arbitrary precision integers.
Definition APInt.h:78
uint64_t getZExtValue() const
Get zero extended value.
Definition APInt.h:1560
static APInt getMaxValue(unsigned numBits)
Gets maximum unsigned value of APInt for specific bit width.
Definition APInt.h:202
static APInt getBitsSet(unsigned numBits, unsigned loBit, unsigned hiBit)
Get a value with a block of bits set.
Definition APInt.h:254
static APInt getSignedMaxValue(unsigned numBits)
Gets maximum signed value of APInt for a specific bit width.
Definition APInt.h:205
static APInt getSignedMinValue(unsigned numBits)
Gets minimum signed value of APInt for a specific bit width.
Definition APInt.h:215
static APInt getLowBitsSet(unsigned numBits, unsigned loBitsSet)
Constructs an APInt value that has the bottom loBitsSet bits set.
Definition APInt.h:302
static APInt getHighBitsSet(unsigned numBits, unsigned hiBitsSet)
Constructs an APInt value that has the top hiBitsSet bits set.
Definition APInt.h:292
This class represents an incoming formal argument to a Function.
Definition Argument.h:32
const BlockAddress * getBlockAddress() const
CCState - This class holds information needed while lowering arguments and return values.
static CCValAssign getCustomMem(unsigned ValNo, MVT ValVT, int64_t Offset, MVT LocVT, LocInfo HTP)
const APFloat & getValueAPF() const
bool isNegative() const
Return true if the value is negative.
uint64_t getZExtValue() const
const APInt & getAPIntValue() const
A parsed version of the target data layout string in and methods for querying it.
Definition DataLayout.h:64
Diagnostic information for unsupported feature in backend.
const DataLayout & getDataLayout() const
Get the data layout of the module this function belongs to.
Definition Function.cpp:356
iterator_range< arg_iterator > args()
Definition Function.h:877
CallingConv::ID getCallingConv() const
getCallingConv()/setCallingConv(CC) - These method get and set the calling convention of this functio...
Definition Function.h:273
LLVMContext & getContext() const
getContext - Return a reference to the LLVMContext associated with this function.
Definition Function.cpp:352
This is an important class for using LLVM in a threaded context.
Definition LLVMContext.h:76
LLVM_ABI void diagnose(const DiagnosticInfo &DI)
Report a message to the currently installed diagnostic handler.
This class is used to represent ISD::LOAD nodes.
const SDValue & getBasePtr() const
Machine Value Type.
static auto integer_fixedlen_vector_valuetypes()
uint64_t getScalarSizeInBits() const
unsigned getVectorNumElements() const
bool isVector() const
Return true if this is a vector value type.
bool isInteger() const
Return true if this is an integer or a vector integer type.
static auto integer_valuetypes()
bool isFloatingPoint() const
Return true if this is a FP or a vector FP type.
MVT getScalarType() const
If this is a vector, return the element type, otherwise return this.
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted.
LLVM_ABI int CreateFixedObject(uint64_t Size, int64_t SPOffset, bool IsImmutable, bool isAliased=false)
Create a new object at a fixed location on the stack.
int64_t getObjectSize(int ObjectIdx) const
Return the size of the specified object.
int64_t getObjectOffset(int ObjectIdx) const
Return the assigned stack offset of the specified object from the incoming stack pointer.
int getObjectIndexBegin() const
Return the minimum frame object index.
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
DenormalMode getDenormalMode(const fltSemantics &FPType) const
Returns the denormal handling type for the default rounding mode of the function.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
Function & getFunction()
Return the LLVM function that this machine code represents.
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
Representation of each machine instruction.
A description of a memory reference used in the backend.
@ MODereferenceable
The memory access is dereferenceable (i.e., doesn't trap).
@ MOInvariant
The memory access always returns the same value (or traps).
Flags getFlags() const
Return the raw flags of the source value,.
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
LLVM_ABI bool hasOneNonDBGUse(Register RegNo) const
hasOneNonDBGUse - Return true if there is exactly one non-Debug use of the specified register.
LLVM_ABI LLVM_READONLY MachineInstr * getVRegDef(Register Reg) const
getVRegDef - Return the machine instr that defines the specified virtual register or null if none is ...
LLVM_ABI Register createVirtualRegister(const TargetRegisterClass *RegClass, StringRef Name="")
createVirtualRegister - Create and return a new virtual register in the function with the specified r...
LLVM_ABI bool isLiveIn(Register Reg) const
LLVM_ABI Register getLiveInVirtReg(MCRegister PReg) const
getLiveInVirtReg - If PReg is a live-in physical register, return the corresponding live-in virtual r...
void addLiveIn(MCRegister Reg, Register vreg=Register())
addLiveIn - Add the specified register as a live-in.
This is an abstract virtual class for memory operations.
unsigned getAddressSpace() const
Return the address space for the associated pointer.
Align getAlign() const
bool isSimple() const
Returns true if the memory operation is neither atomic or volatile.
MachineMemOperand * getMemOperand() const
Return the unique MachineMemOperand object describing the memory reference performed by operation.
const SDValue & getChain() const
bool isInvariant() const
EVT getMemoryVT() const
Return the type of the in-memory value.
Wrapper class representing virtual and physical registers.
Definition Register.h:20
Wrapper class for IR location info (IR ordering and DebugLoc) to be passed into SDNode creation funct...
const DebugLoc & getDebugLoc() const
Represents one node in the SelectionDAG.
ArrayRef< SDUse > ops() const
unsigned getOpcode() const
Return the SelectionDAG opcode value for this node.
bool hasOneUse() const
Return true if there is exactly one use of this node.
SDNodeFlags getFlags() const
SDVTList getVTList() const
const SDValue & getOperand(unsigned Num) const
uint64_t getConstantOperandVal(unsigned Num) const
Helper method returns the integer value of a ConstantSDNode operand.
EVT getValueType(unsigned ResNo) const
Return the type of a specified result.
iterator_range< user_iterator > users()
Represents a use of a SDNode.
Unlike LLVM values, Selection DAG nodes may return multiple values as the result of a computation.
SDNode * getNode() const
get the SDNode which holds the desired result
bool hasOneUse() const
Return true if there is exactly one node using value ResNo of Node, in exactly one operand.
SDValue getValue(unsigned R) const
EVT getValueType() const
Return the ValueType of the referenced return value.
TypeSize getValueSizeInBits() const
Returns the size of the value in bits.
const SDValue & getOperand(unsigned i) const
unsigned getOpcode() const
unsigned getNumOperands() const
This class keeps track of the SPI_SP_INPUT_ADDR config register, which tells the hardware which inter...
SIModeRegisterDefaults getMode() const
This is used to represent a portion of an LLVM function in a low-level Data Dependence DAG representa...
LLVM_ABI bool isKnownNeverLogicalZero(SDValue Op, const APInt &DemandedElts, unsigned Depth=0) const
Test whether the given floating point SDValue (or all elements of it, if it is a vector) is known to ...
SDValue getExtOrTrunc(SDValue Op, const SDLoc &DL, EVT VT, unsigned Opcode)
Convert Op, which must be of integer type, to the integer type VT, by either any/sign/zero-extending ...
LLVM_ABI unsigned ComputeMaxSignificantBits(SDValue Op, unsigned Depth=0) const
Get the upper bound on bit size for this Value Op as a signed integer.
const SDValue & getRoot() const
Return the root tag of the SelectionDAG.
const TargetSubtargetInfo & getSubtarget() const
LLVM_ABI SDValue getMergeValues(ArrayRef< SDValue > Ops, const SDLoc &dl)
Create a MERGE_VALUES node from the given operands.
LLVM_ABI SDVTList getVTList(EVT VT)
Return an SDVTList that represents the list of values specified.
LLVM_ABI SDValue getShiftAmountConstant(uint64_t Val, EVT VT, const SDLoc &DL)
LLVM_ABI SDValue getAllOnesConstant(const SDLoc &DL, EVT VT, bool IsTarget=false, bool IsOpaque=false)
LLVM_ABI void ExtractVectorElements(SDValue Op, SmallVectorImpl< SDValue > &Args, unsigned Start=0, unsigned Count=0, EVT EltVT=EVT())
Append the extracted elements from Start to Count out of the vector Op in Args.
LLVM_ABI SDValue getFreeze(SDValue V)
Return a freeze using the SDLoc of the value operand.
LLVM_ABI SDValue getConstantFP(double Val, const SDLoc &DL, EVT VT, bool isTarget=false)
Create a ConstantFPSDNode wrapping a constant value.
LLVM_ABI SDValue getRegister(Register Reg, EVT VT)
SDValue getSetCC(const SDLoc &DL, EVT VT, SDValue LHS, SDValue RHS, ISD::CondCode Cond, SDValue Chain=SDValue(), bool IsSignaling=false, SDNodeFlags Flags={})
Helper function to make it easier to build SetCC's if you just have an ISD::CondCode instead of an SD...
LLVM_ABI SDValue getNOT(const SDLoc &DL, SDValue Val, EVT VT)
Create a bitwise NOT operation as (XOR Val, -1).
const TargetLowering & getTargetLoweringInfo() const
SDValue getCALLSEQ_END(SDValue Chain, SDValue Op1, SDValue Op2, SDValue InGlue, const SDLoc &DL)
Return a new CALLSEQ_END node, which always must have a glue result (to ensure it's not CSE'd).
SDValue getBuildVector(EVT VT, const SDLoc &DL, ArrayRef< SDValue > Ops)
Return an ISD::BUILD_VECTOR node.
LLVM_ABI SDValue getTruncStore(SDValue Chain, const SDLoc &dl, SDValue Val, SDValue Ptr, SDValue Offset, MachinePointerInfo PtrInfo, EVT SVT, Align Alignment, MachineMemOperand::Flags MMOFlags=MachineMemOperand::MONone, const MMOMetadata &Metadata=MMOMetadata())
LLVM_ABI SDValue getBitcast(EVT VT, SDValue V)
Return a bitcast using the SDLoc of the value operand, and casting to the provided type.
SDValue getCopyFromReg(SDValue Chain, const SDLoc &dl, Register Reg, EVT VT)
SDValue getSelect(const SDLoc &DL, EVT VT, SDValue Cond, SDValue LHS, SDValue RHS, SDNodeFlags Flags=SDNodeFlags())
Helper function to make it easier to build Select's if you just have operands and don't want to check...
LLVM_ABI SDValue getZeroExtendInReg(SDValue Op, const SDLoc &DL, EVT VT)
Return the expression required to zero extend the Op value assuming it was the smaller SrcTy value.
const DataLayout & getDataLayout() const
LLVM_ABI SDValue getStore(SDValue Chain, const SDLoc &dl, SDValue Val, SDValue Ptr, MachinePointerInfo PtrInfo, Align Alignment, MachineMemOperand::Flags MMOFlags=MachineMemOperand::MONone, const MMOMetadata &Metadata=MMOMetadata())
Helper function to build ISD::STORE nodes.
LLVM_ABI SDValue getConstant(uint64_t Val, const SDLoc &DL, EVT VT, bool isTarget=false, bool isOpaque=false)
Create a ConstantSDNode wrapping a constant value.
LLVM_ABI void ReplaceAllUsesWith(SDValue From, SDValue To)
Modify anything using 'From' to use 'To' instead.
LLVM_ABI SDValue getExtLoad(ISD::LoadExtType ExtType, const SDLoc &dl, EVT VT, SDValue Chain, SDValue Ptr, MachinePointerInfo PtrInfo, EVT MemVT, MaybeAlign Alignment=MaybeAlign(), MachineMemOperand::Flags MMOFlags=MachineMemOperand::MONone, const MMOMetadata &Metadata=MMOMetadata())
LLVM_ABI SDValue getSignedConstant(int64_t Val, const SDLoc &DL, EVT VT, bool isTarget=false, bool isOpaque=false)
SDValue getCALLSEQ_START(SDValue Chain, uint64_t InSize, uint64_t OutSize, const SDLoc &DL)
Return a new CALLSEQ_START node, that starts new call frame, in which InSize bytes are set up inside ...
bool isConstantValueOfAnyType(SDValue N) const
SDValue getSelectCC(const SDLoc &DL, SDValue LHS, SDValue RHS, SDValue True, SDValue False, ISD::CondCode Cond, SDNodeFlags Flags=SDNodeFlags())
Helper function to make it easier to build SelectCC's if you just have an ISD::CondCode instead of an...
LLVM_ABI SDValue getSExtOrTrunc(SDValue Op, const SDLoc &DL, EVT VT)
Convert Op, which must be of integer type, to the integer type VT, by either sign-extending or trunca...
LLVM_ABI SDValue getLoad(EVT VT, const SDLoc &dl, SDValue Chain, SDValue Ptr, MachinePointerInfo PtrInfo, MaybeAlign Alignment=MaybeAlign(), MachineMemOperand::Flags MMOFlags=MachineMemOperand::MONone, const MMOMetadata &Metadata=MMOMetadata())
Loads are not normal binary operators: their result type is not determined by their operands,...
LLVM_ABI KnownFPClass computeKnownFPClass(SDValue Op, FPClassTest InterestedClasses, unsigned Depth=0) const
Determine floating-point class information about Op.
LLVM_ABI bool isGuaranteedNotToBeUndefOrPoison(SDValue Op, UndefPoisonKind Kind=UndefPoisonKind::UndefOrPoison, unsigned Depth=0) const
Return true if this function can prove that Op is never poison and, Kind can be used to track poison ...
LLVM_ABI SDValue getIntPtrConstant(uint64_t Val, const SDLoc &DL, bool isTarget=false)
LLVM_ABI SDValue getValueType(EVT)
LLVM_ABI SDValue getNode(unsigned Opcode, const SDLoc &DL, EVT VT, ArrayRef< SDUse > Ops)
Gets or creates the specified node.
LLVM_ABI bool isKnownNeverNaN(SDValue Op, const APInt &DemandedElts, bool SNaN=false, unsigned Depth=0) const
Test whether the given SDValue (or all elements of it, if it is a vector) is known to never be NaN in...
SDValue getTargetConstant(uint64_t Val, const SDLoc &DL, EVT VT, bool isOpaque=false)
LLVM_ABI unsigned ComputeNumSignBits(SDValue Op, unsigned Depth=0) const
Return the number of times the sign bit of the register is replicated into the other bits.
SDValue getTargetBlockAddress(const BlockAddress *BA, EVT VT, int64_t Offset=0, unsigned TargetFlags=0)
LLVM_ABI SDValue getVectorIdxConstant(uint64_t Val, const SDLoc &DL, bool isTarget=false)
LLVM_ABI void ReplaceAllUsesOfValueWith(SDValue From, SDValue To)
Replace any uses of From with To, leaving uses of other values produced by From.getNode() alone.
MachineFunction & getMachineFunction() const
SDValue getPOISON(EVT VT)
Return a POISON node. POISON does not have a useful SDLoc.
LLVM_ABI SDValue getFrameIndex(int FI, EVT VT, bool isTarget=false)
LLVM_ABI KnownBits computeKnownBits(SDValue Op, unsigned Depth=0) const
Determine which bits of Op are known to be either zero or one and return them in Known.
LLVM_ABI SDValue getZExtOrTrunc(SDValue Op, const SDLoc &DL, EVT VT)
Convert Op, which must be of integer type, to the integer type VT, by either zero-extending or trunca...
LLVM_ABI bool MaskedValueIsZero(SDValue Op, const APInt &Mask, unsigned Depth=0) const
Return true if 'Op & Mask' is known to be zero.
SDValue getObjectPtrOffset(const SDLoc &SL, SDValue Ptr, TypeSize Offset)
Create an add instruction with appropriate flags when used for addressing some offset of an object.
LLVMContext * getContext() const
const SDValue & setRoot(SDValue N)
Set the current root tag of the SelectionDAG.
LLVM_ABI SDNode * UpdateNodeOperands(SDNode *N, SDValue Op)
Mutate the specified node in-place to have the specified operands.
SDValue getEntryNode() const
Return the token chain corresponding to the entry of the function.
LLVM_ABI std::pair< SDValue, SDValue > SplitScalar(const SDValue &N, const SDLoc &DL, const EVT &LoVT, const EVT &HiVT)
Split the scalar node with EXTRACT_ELEMENT using the provided VTs and return the low/high part.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
This class is used to represent ISD::STORE nodes.
const SDValue & getBasePtr() const
const SDValue & getValue() const
Represent a constant reference to a string, i.e.
Definition StringRef.h:56
void setOperationAction(unsigned Op, MVT VT, LegalizeAction Action)
Indicate that the specified operation does not work with the specified type and indicate what to do a...
void setMaxDivRemBitWidthSupported(unsigned SizeInBits)
Set the size in bits of the maximum div/rem the backend supports.
bool PredictableSelectIsExpensive
Tells the code generator that select is more expensive than a branch if the branch is usually predict...
virtual bool shouldReduceLoadWidth(SDNode *Load, ISD::LoadExtType ExtTy, EVT NewVT, std::optional< unsigned > ByteOffset=std::nullopt) const
Return true if it is profitable to reduce a load to a smaller type.
unsigned MaxStoresPerMemcpyOptSize
Likewise for functions with the OptSize attribute.
const TargetMachine & getTargetMachine() const
virtual unsigned getNumRegistersForCallingConv(LLVMContext &Context, CallingConv::ID CC, EVT VT) const
Certain targets require unusual breakdowns of certain types.
unsigned MaxGluedStoresPerMemcpy
Specify max number of store instructions to glue in inlined memcpy.
virtual MVT getRegisterTypeForCallingConv(LLVMContext &Context, CallingConv::ID CC, EVT VT) const
Certain combinations of ABIs, Targets and features require that types are legal for some operations a...
void addBypassSlowDiv(unsigned int SlowBitWidth, unsigned int FastBitWidth)
Tells the code generator which bitwidths to bypass.
void setMaxLargeFPConvertBitWidthSupported(unsigned SizeInBits)
Set the size in bits of the maximum fp to/from int conversion the backend supports.
void setMaxAtomicSizeInBitsSupported(unsigned SizeInBits)
Set the maximum atomic operation size supported by the backend.
SelectSupportKind
Enum that describes what type of support for selects the target has.
virtual bool allowsMisalignedMemoryAccesses(EVT, unsigned AddrSpace=0, Align Alignment=Align(1), MachineMemOperand::Flags Flags=MachineMemOperand::MONone, unsigned *=nullptr) const
Determine if the target supports unaligned memory accesses.
unsigned MaxStoresPerMemsetOptSize
Likewise for functions with the OptSize attribute.
EVT getShiftAmountTy(EVT LHSTy, const DataLayout &DL) const
Returns the type for the shift amount of a shift opcode.
unsigned MaxStoresPerMemmove
Specify maximum number of store instructions per memmove call.
virtual EVT getSetCCResultType(const DataLayout &DL, LLVMContext &Context, EVT VT) const
Return the ValueType of the result of SETCC operations.
unsigned MaxStoresPerMemmoveOptSize
Likewise for functions with the OptSize attribute.
bool isTypeLegal(EVT VT) const
Return true if the target has native support for the specified value type.
void setSupportsUnalignedAtomics(bool UnalignedSupported)
Sets whether unaligned atomic operations are supported.
bool isOperationLegal(unsigned Op, EVT VT) const
Return true if the specified operation is legal on this target.
unsigned MaxStoresPerMemset
Specify maximum number of store instructions per memset call.
FPImmAction
How the legalizer should materialize a floating-point immediate.
@ ConstantPool
Load the immediate from the constant pool.
@ Legal
The target can instruction select the immediate natively.
void setTruncStoreAction(MVT ValVT, MVT MemVT, LegalizeAction Action)
Indicate that the specified truncating store does not work with the specified type and indicate what ...
void setMinCmpXchgSizeInBits(unsigned SizeInBits)
Sets the minimum cmpxchg or ll/sc size supported by the backend.
void AddPromotedToType(unsigned Opc, MVT OrigVT, MVT DestVT)
If Opc/OrigVT is specified as being promoted, the promotion code defaults to trying a larger integer/...
void setTargetDAGCombine(ArrayRef< ISD::NodeType > NTs)
Targets should invoke this method for each target independent node that they want to provide a custom...
void setLoadExtAction(unsigned ExtType, MVT ValVT, MVT MemVT, LegalizeAction Action)
Indicate that the specified load with extension does not work with the specified type and indicate wh...
unsigned GatherAllAliasesMaxDepth
Depth that GatherAllAliases should continue looking for chain dependencies when trying to find a more...
NegatibleCost
Enum that specifies when a float negation is beneficial.
bool allowsMemoryAccessForAlignment(LLVMContext &Context, const DataLayout &DL, EVT VT, unsigned AddrSpace=0, Align Alignment=Align(1), MachineMemOperand::Flags Flags=MachineMemOperand::MONone, unsigned *Fast=nullptr) const
This function returns true if the memory access is aligned or if the target allows this specific unal...
unsigned MaxStoresPerMemcpy
Specify maximum number of store instructions per memcpy call.
void setSchedulingPreference(Sched::Preference Pref)
Specify the target scheduling preference.
void setJumpIsExpensive(bool isExpensive=true)
Tells the code generator not to expand logic operations on comparison predicates into separate sequen...
This class defines information used to lower LLVM code to legal SelectionDAG operators that the targe...
SDValue scalarizeVectorStore(StoreSDNode *ST, SelectionDAG &DAG) const
SDValue SimplifyMultipleUseDemandedBits(SDValue Op, const APInt &DemandedBits, const APInt &DemandedElts, SelectionDAG &DAG, unsigned Depth=0) const
More limited version of SimplifyDemandedBits that can be used to "lookthrough" ops that don't contrib...
SDValue expandUnalignedStore(StoreSDNode *ST, SelectionDAG &DAG) const
Expands an unaligned store to 2 half-size stores for integer values, and possibly more for vectors.
bool ShrinkDemandedConstant(SDValue Op, const APInt &DemandedBits, const APInt &DemandedElts, TargetLoweringOpt &TLO) const
Check to see if the specified operand of the specified instruction is a constant integer.
std::pair< SDValue, SDValue > expandUnalignedLoad(LoadSDNode *LD, SelectionDAG &DAG) const
Expands an unaligned load to 2 half-size loads for an integer, and possibly more for vectors.
virtual SDValue getNegatedExpression(SDValue Op, SelectionDAG &DAG, bool LegalOps, bool OptForSize, NegatibleCost &Cost, unsigned Depth=0) const
Return the newly negated expression if the cost is not expensive and set the cost in Cost to indicate...
std::pair< SDValue, SDValue > scalarizeVectorLoad(LoadSDNode *LD, SelectionDAG &DAG) const
Turn load of vector type into a load of the individual elements.
bool SimplifyDemandedBits(SDValue Op, const APInt &DemandedBits, const APInt &DemandedElts, KnownBits &Known, TargetLoweringOpt &TLO, unsigned Depth=0, bool AssumeSingleUse=false) const
Look at Op.
TargetLowering(const TargetLowering &)=delete
virtual bool canCreateUndefOrPoisonForTargetNode(SDValue Op, const APInt &DemandedElts, const SelectionDAG &DAG, UndefPoisonKind Kind, bool ConsiderFlags, unsigned Depth) const
Return true if Op can create undef or poison from non-undef & non-poison operands.
Primary interface to the complete machine description for the target machine.
TargetSubtargetInfo - Generic base class for all target subtargets.
static constexpr TypeSize getFixed(ScalarTy ExactSize)
Definition TypeSize.h:348
The instances of the Type class are immutable: once they are created, they are never changed.
Definition Type.h:46
LLVM_ABI unsigned getScalarSizeInBits() const LLVM_READONLY
If this is a vector type, return the getPrimitiveSizeInBits value for the element type.
Definition Type.cpp:222
LLVM Value Representation.
Definition Value.h:75
LLVM_ABI StringRef getName() const
Return a constant reference to the value's name.
Definition Value.cpp:315
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ CONSTANT_ADDRESS_32BIT
Address space for 32-bit constant memory.
@ BARRIER
Address space for modeling barrier IDs as addresses.
@ REGION_ADDRESS
Address space for region memory. (GDS)
@ LOCAL_ADDRESS
Address space for local memory.
@ CONSTANT_ADDRESS
Address space for constant memory (VTX2).
@ GLOBAL_ADDRESS
Address space for global memory (RAT0, VTX0).
bool isIntrinsicAlwaysUniform(unsigned IntrID)
TargetExtType * isNamedBarrier(const GlobalVariable &GV)
std::optional< APFloat > evaluateRcp(const APFloat &Val)
Evaluate the constant-folded result of v_rcp for Val, accounting for the hardware's denormal flushing...
bool isUniformMMO(const MachineMemOperand *MMO)
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
Definition CallingConv.h:24
@ AMDGPU_CS
Used for Mesa/AMDPAL compute shaders.
@ AMDGPU_VS
Used for Mesa vertex shaders, or AMDPAL last shader stage before rasterization (vertex shader if tess...
@ AMDGPU_KERNEL
Used for AMDGPU code object kernels.
@ AMDGPU_Gfx
Used for AMD graphics targets.
@ AMDGPU_CS_ChainPreserve
Used on AMDGPUs to give the middle-end more control over argument placement.
@ AMDGPU_HS
Used for Mesa/AMDPAL hull shaders (= tessellation control shaders).
@ AMDGPU_GS
Used for Mesa/AMDPAL geometry shaders.
@ AMDGPU_CS_Chain
Used on AMDGPUs to give the middle-end more control over argument placement.
@ AMDGPU_PS
Used for Mesa/AMDPAL pixel shaders.
@ Cold
Attempts to make code in the caller as efficient as possible under the assumption that the call is no...
Definition CallingConv.h:47
@ SPIR_KERNEL
Used for SPIR kernel functions.
@ Fast
Attempts to make calls as fast as possible (e.g.
Definition CallingConv.h:41
@ AMDGPU_ES
Used for AMDPAL shader stage before geometry shader if geometry is in use.
@ AMDGPU_LS
Used for AMDPAL vertex shader if tessellation is in use.
@ C
The default llvm calling convention, compatible with C.
Definition CallingConv.h:34
NodeType
ISD::NodeType enum - This enum defines the target-independent operators for a SelectionDAG.
Definition ISDOpcodes.h:43
@ SETCC
SetCC operator - This evaluates to a true value iff the condition is true.
Definition ISDOpcodes.h:845
@ SMUL_LOHI
SMUL_LOHI/UMUL_LOHI - Multiply two integers of type iN, producing a signed/unsigned value of type i[2...
Definition ISDOpcodes.h:277
@ INSERT_SUBVECTOR
INSERT_SUBVECTOR(VECTOR1, VECTOR2, IDX) - Returns a vector with VECTOR2 inserted into VECTOR1.
Definition ISDOpcodes.h:605
@ BSWAP
Byte Swap and Counting operators.
Definition ISDOpcodes.h:805
@ ADDC
Carry-setting nodes for multiple precision addition and subtraction.
Definition ISDOpcodes.h:296
@ FMAD
FMAD - Perform a * b + c, while getting the same result as the separately rounded operations.
Definition ISDOpcodes.h:527
@ ADD
Simple integer binary arithmetic operators.
Definition ISDOpcodes.h:266
@ LOAD
LOAD and STORE have token chains as their first operand, then the same operands as an LLVM load/store...
@ ANY_EXTEND
ANY_EXTEND - Used for integer types. The high bits are undefined.
Definition ISDOpcodes.h:879
@ FMA
FMA - Perform a * b + c with no intermediate rounding step.
Definition ISDOpcodes.h:523
@ SINT_TO_FP
[SU]INT_TO_FP - These operators convert integers (whose interpreted sign depends on the first letter)...
Definition ISDOpcodes.h:906
@ CONCAT_VECTORS
CONCAT_VECTORS(VECTOR0, VECTOR1, ...) - Given a number of values of vector type with the same length ...
Definition ISDOpcodes.h:589
@ FADD
Simple binary floating point operators.
Definition ISDOpcodes.h:420
@ ABS
ABS - Determine the unsigned absolute value of a signed integer value of the same bitwidth.
Definition ISDOpcodes.h:765
@ SDIVREM
SDIVREM/UDIVREM - Divide two integers and produce both a quotient and remainder result.
Definition ISDOpcodes.h:282
@ FP16_TO_FP
FP16_TO_FP, FP_TO_FP16 - These operators are used to perform promotions and truncation for half-preci...
@ BITCAST
BITCAST - This operator converts between integer, vector and FP values, as if the value was stored to...
@ BUILD_PAIR
BUILD_PAIR - This is the opposite of EXTRACT_ELEMENT in some ways.
Definition ISDOpcodes.h:256
@ FLDEXP
FLDEXP - ldexp, inspired by libm (op0 * 2**op1).
@ CTLZ_ZERO_POISON
Definition ISDOpcodes.h:814
@ SIGN_EXTEND
Conversion operators.
Definition ISDOpcodes.h:870
@ FNEG
Perform various unary floating-point operations inspired by libm.
@ BRIND
BRIND - Indirect branch.
@ BR_JT
BR_JT - Jumptable branch.
@ FCANONICALIZE
Returns platform specific canonical encoding of a floating point number.
Definition ISDOpcodes.h:546
@ IS_FPCLASS
Performs a check of floating point class property, defined by IEEE-754.
Definition ISDOpcodes.h:553
@ SELECT
Select(COND, TRUEVAL, FALSEVAL).
Definition ISDOpcodes.h:822
@ EXTRACT_ELEMENT
EXTRACT_ELEMENT - This is used to get the lower or upper (determined by a Constant,...
Definition ISDOpcodes.h:249
@ CTLS
Count leading redundant sign bits.
Definition ISDOpcodes.h:818
@ MULHU
MULHU/MULHS - Multiply high - Multiply two integers of type iN, producing an unsigned/signed value of...
Definition ISDOpcodes.h:714
@ STRICT_FP16_TO_FP
@ SHL
Shift and rotation operations.
Definition ISDOpcodes.h:787
@ VECTOR_SHUFFLE
VECTOR_SHUFFLE(VEC1, VEC2) - Returns a vector, of the same type as VEC1/VEC2.
Definition ISDOpcodes.h:659
@ EXTRACT_SUBVECTOR
EXTRACT_SUBVECTOR(VECTOR, IDX) - Returns a subvector from VECTOR.
Definition ISDOpcodes.h:619
@ FMINNUM_IEEE
FMINNUM_IEEE/FMAXNUM_IEEE - Same as FMINNUM/FMAXNUM, except that a signaling NaN operand deterministi...
@ EntryToken
EntryToken - This is the marker used to indicate the start of a region.
Definition ISDOpcodes.h:50
@ EXTRACT_VECTOR_ELT
EXTRACT_VECTOR_ELT(VECTOR, IDX) - Returns a single element from VECTOR identified by the (potentially...
Definition ISDOpcodes.h:581
@ CopyToReg
CopyToReg - This node has three operands: a chain, a register number to set to this value,...
Definition ISDOpcodes.h:226
@ ZERO_EXTEND
ZERO_EXTEND - Used for integer types, zeroing the new bits.
Definition ISDOpcodes.h:876
@ SELECT_CC
Select with condition operator - This selects between a true value and a false value (ops #2 and #3) ...
Definition ISDOpcodes.h:837
@ FMINNUM
FMINNUM/FMAXNUM - Same semantics as the llvm.minnum/maxnum intrinsics.
@ DYNAMIC_STACKALLOC
DYNAMIC_STACKALLOC - Allocate some number of bytes on the stack aligned to a specified boundary.
@ SIGN_EXTEND_INREG
SIGN_EXTEND_INREG - This operator atomically performs a SHL/SRA pair to sign extend a small value in ...
Definition ISDOpcodes.h:914
@ SMIN
[US]{MIN/MAX} - Binary minimum or maximum of signed or unsigned integers.
Definition ISDOpcodes.h:745
@ FP_EXTEND
X = FP_EXTEND(Y) - Extend a smaller FP type into a larger FP type.
@ VSELECT
Select with a vector condition (op #0) and two vector operands (ops #1 and #2), returning a vector re...
Definition ISDOpcodes.h:831
@ UADDO_CARRY
Carry-using nodes for multiple precision addition and subtraction.
Definition ISDOpcodes.h:331
@ INLINEASM_BR
INLINEASM_BR - Branching version of inline asm. Used by asm-goto.
@ FMINIMUM
FMINIMUM/FMAXIMUM - Same semantics as the llvm.minimum/maximum intrinsics.
@ FP_TO_SINT
FP_TO_[US]INT - Convert a floating point value to a signed or unsigned integer.
Definition ISDOpcodes.h:952
@ AND
Bitwise operators - logical and, logical or, logical xor.
Definition ISDOpcodes.h:757
@ TRAP
TRAP - Trapping instruction.
@ INTRINSIC_WO_CHAIN
RESULT = INTRINSIC_WO_CHAIN(INTRINSICID, arg1, arg2, ...) This node represents a target intrinsic fun...
Definition ISDOpcodes.h:207
@ ADDE
Carry-using nodes for multiple precision addition and subtraction.
Definition ISDOpcodes.h:306
@ INSERT_VECTOR_ELT
INSERT_VECTOR_ELT(VECTOR, VAL, IDX) - Returns VECTOR with the element at IDX replaced with VAL.
Definition ISDOpcodes.h:570
@ TokenFactor
TokenFactor - This node takes multiple tokens as input and produces a single token result.
Definition ISDOpcodes.h:55
@ CTTZ_ZERO_POISON
Bit counting operators with a poisoned result for zero inputs.
Definition ISDOpcodes.h:813
@ FFREXP
FFREXP - frexp, extract fractional and exponent component of a floating-point value.
@ FP_ROUND
X = FP_ROUND(Y, TRUNC) - Rounding 'Y' from a larger floating point type down to the precision of the ...
Definition ISDOpcodes.h:985
@ ADDRSPACECAST
ADDRSPACECAST - This operator converts between pointers of different address spaces.
@ INLINEASM
INLINEASM - Represents an inline asm block.
@ FP_TO_SINT_SAT
FP_TO_[US]INT_SAT - Convert floating point value in operand 0 to a signed or unsigned scalar integer ...
Definition ISDOpcodes.h:971
@ TRUNCATE
TRUNCATE - Completely drop the high bits.
Definition ISDOpcodes.h:882
@ AssertSext
AssertSext, AssertZext - These nodes record if a register contains a value that has already been zero...
Definition ISDOpcodes.h:64
@ FCOPYSIGN
FCOPYSIGN(X, Y) - Return the value of X with the sign of Y.
Definition ISDOpcodes.h:539
@ FMINIMUMNUM
FMINIMUMNUM/FMAXIMUMNUM - Same semantics as the llvm.minimumnum/maximumnum intrinsics.
@ INTRINSIC_W_CHAIN
RESULT,OUTCHAIN = INTRINSIC_W_CHAIN(INCHAIN, INTRINSICID, arg1, ...) This node represents a target in...
Definition ISDOpcodes.h:215
@ BUILD_VECTOR
BUILD_VECTOR(ELT0, ELT1, ELT2, ELT3,...) - Return a fixed-width vector with the specified,...
Definition ISDOpcodes.h:561
bool isNormalStore(const SDNode *N)
Returns true if the specified node is a non-truncating and unindexed store.
LLVM_ABI CondCode getSetCCInverse(CondCode Operation, EVT Type)
Return the operation corresponding to !(X op Y), where 'op' is a valid SetCC operation.
CondCode
ISD::CondCode enum - These are ordered carefully to make the bitfields below work out,...
LoadExtType
LoadExtType enum - This enum defines the three variants of LOADEXT (load with extension).
bool isNormalLoad(const SDNode *N)
Returns true if the specified node is a non-extending and unindexed load.
initializer< Ty > init(const Ty &Val)
constexpr double ln2
constexpr double ln10
constexpr float log2ef
Definition MathExtras.h:52
constexpr double log2e
This is an optimization pass for GlobalISel generic memory operations.
@ Offset
Definition DWP.cpp:577
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1755
InstructionCost Cost
LLVM_ABI bool isNullConstant(SDValue V)
Returns true if V is a constant integer zero.
@ Known
Known to have no common set bits.
LLVM_ABI void ComputeValueVTs(const TargetLowering &TLI, const DataLayout &DL, Type *Ty, SmallVectorImpl< EVT > &ValueVTs, SmallVectorImpl< EVT > *MemVTs=nullptr, SmallVectorImpl< TypeSize > *Offsets=nullptr, TypeSize StartingOffset=TypeSize::getZero())
ComputeValueVTs - Given an LLVM IR type, compute a sequence of EVTs that represent all the individual...
Definition Analysis.cpp:121
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:643
bool CCAssignFn(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, Type *OrigTy, CCState &State)
CCAssignFn - This function assigns a location for Val, updating State to reflect the change.
@ Load
The value being inserted comes from a load (InsertElement only).
@ Store
The extracted value is stored (ExtractElement only).
SDValue peekFPSignOps(SDValue Val)
Strip fabs/fneg/fcopysign from a value to get the underlying source.
LLVM_ABI ConstantFPSDNode * isConstOrConstSplatFP(SDValue N, bool AllowUndefs=false)
Returns the SDNode if it is a constant splat BuildVector or constant float.
uint64_t PowerOf2Ceil(uint64_t A)
Returns the power of two which is greater than or equal to the given value.
Definition MathExtras.h:380
int countr_zero(T Val)
Count number of 0's from the least significant bit to the most stopping at the first 1.
Definition bit.h:204
int countl_zero(T Val)
Count number of 0's from the most significant bit to the least stopping at the first 1.
Definition bit.h:263
decltype(auto) get(const PointerIntPair< PointerTy, IntBits, IntType, PtrTraits, Info > &Pair)
FPClassTest
Floating-point class tests, supported by 'is_fpclass' intrinsic.
constexpr uint32_t Hi_32(uint64_t Value)
Return the high 32 bits of a 64 bit value.
Definition MathExtras.h:151
constexpr uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
Definition Alignment.h:149
constexpr bool isUInt(uint64_t x)
Checks if an unsigned integer fits into the given bit width.
Definition MathExtras.h:190
constexpr uint32_t Lo_32(uint64_t Value)
Return the low 32 bits of a 64 bit value.
Definition MathExtras.h:156
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
Definition Casting.h:547
LLVM_ABI raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
CombineLevel
Definition DAGCombine.h:15
@ AfterLegalizeDAG
Definition DAGCombine.h:19
@ BeforeLegalizeTypes
Definition DAGCombine.h:16
@ AfterLegalizeTypes
Definition DAGCombine.h:17
To bit_cast(const From &from) noexcept
Definition bit.h:90
@ Mul
Product of integers.
@ Add
Sum of integers.
@ Fast
Assign the register banks as fast as possible (default).
DWARFExpression::Operation Op
LLVM_ABI ConstantSDNode * isConstOrConstSplat(SDValue N, bool AllowUndefs=false, bool AllowTruncation=false)
Returns the SDNode if it is a constant splat BuildVector or constant int.
constexpr unsigned BitWidth
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:559
LLVM_ABI bool isOneConstant(SDValue V)
Returns true if V is a constant integer one.
UndefPoisonKind
Enumeration to track whether we are interested in Undef, Poison, or both.
Definition UndefPoison.h:20
Align commonAlignment(Align A, uint64_t Offset)
Returns the alignment that satisfies both alignments.
Definition Alignment.h:206
APFloat neg(APFloat X)
Returns the negated value of the argument.
Definition APFloat.h:1727
unsigned Log2(Align A)
Returns the log2 of the alignment.
Definition Alignment.h:202
LLVM_ABI bool isAllOnesConstant(SDValue V)
Returns true if V is an integer constant with all bits set.
MCRegisterClass TargetRegisterClass
Definition FastISel.h:58
LLVM_ABI void reportFatalUsageError(Error Err)
Report a fatal error that does not indicate a bug in LLVM.
Definition Error.cpp:177
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
Definition BitVector.h:880
#define N
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition Alignment.h:39
MCRegister getRegister() const
unsigned getStackOffset() const
DenormalModeKind Input
Denormal treatment kind for floating point instruction inputs in the default floating-point environme...
@ PreserveSign
The sign of a flushed-to-zero number is preserved in the sign of 0.
constexpr bool inputsAreZero() const
Return true if input denormals must be implicitly treated as 0.
static constexpr DenormalMode getPreserveSign()
Extended Value Type.
Definition ValueTypes.h:35
TypeSize getStoreSize() const
Return the number of bytes overwritten by a store of the specified value type.
Definition ValueTypes.h:418
EVT getPow2VectorType(LLVMContext &Context) const
Widens the length of the given vector EVT up to the nearest power of 2 and returns that type.
Definition ValueTypes.h:508
bool isSimple() const
Test if the given EVT is simple (as opposed to being extended).
Definition ValueTypes.h:145
static EVT getVectorVT(LLVMContext &Context, EVT VT, unsigned NumElements, bool IsScalable=false)
Returns the EVT that represents a vector NumElements in length, where each element is of type VT.
Definition ValueTypes.h:70
EVT changeTypeToInteger() const
Return the type converted to an equivalently sized integer or vector with integer element type.
Definition ValueTypes.h:129
bool bitsGT(EVT VT) const
Return true if this has more bits than VT.
Definition ValueTypes.h:307
bool isFloatingPoint() const
Return true if this is a FP or a vector FP type.
Definition ValueTypes.h:155
TypeSize getSizeInBits() const
Return the size of the specified value type in bits.
Definition ValueTypes.h:396
bool isByteSized() const
Return true if the bit size is a multiple of 8.
Definition ValueTypes.h:266
uint64_t getScalarSizeInBits() const
Definition ValueTypes.h:408
EVT getHalfSizedIntegerVT(LLVMContext &Context) const
Finds the smallest simple value type that is greater than or equal to half the width of this EVT.
Definition ValueTypes.h:453
bool isPow2VectorType() const
Returns true if the given vector is a power of 2.
Definition ValueTypes.h:501
TypeSize getStoreSizeInBits() const
Return the number of bits overwritten by a store of the specified value type.
Definition ValueTypes.h:435
MVT getSimpleVT() const
Return the SimpleValueType held in the specified simple EVT.
Definition ValueTypes.h:339
static EVT getIntegerVT(LLVMContext &Context, unsigned BitWidth)
Returns the EVT that represents an integer with the given number of bits.
Definition ValueTypes.h:61
uint64_t getFixedSizeInBits() const
Return the size of the specified fixed width value type in bits.
Definition ValueTypes.h:404
EVT getRoundIntegerType(LLVMContext &Context) const
Rounds the bit-width of the given integer EVT up to the nearest power of two (and at least to eight),...
Definition ValueTypes.h:442
bool isVector() const
Return true if this is a vector value type.
Definition ValueTypes.h:176
EVT getScalarType() const
If this is a vector type, return the element type, otherwise return this.
Definition ValueTypes.h:346
bool bitsGE(EVT VT) const
Return true if this has no less bits than VT.
Definition ValueTypes.h:315
EVT getVectorElementType() const
Given a vector type, return the type of each element.
Definition ValueTypes.h:351
bool isExtended() const
Test if the given EVT is extended (as opposed to being simple).
Definition ValueTypes.h:150
EVT changeElementType(LLVMContext &Context, EVT EltVT) const
Return a VT for a type whose attributes match ourselves with the exception of the element type that i...
Definition ValueTypes.h:121
LLVM_ABI const fltSemantics & getFltSemantics() const
Returns an APFloat semantics tag appropriate for the value type.
unsigned getVectorNumElements() const
Given a vector type, return the number of elements it contains.
Definition ValueTypes.h:359
bool bitsLE(EVT VT) const
Return true if this has no more bits than VT.
Definition ValueTypes.h:331
bool isInteger() const
Return true if this is an integer or a vector integer type.
Definition ValueTypes.h:160
InputArg - This struct carries flags and type information about a single incoming (formal) argument o...
MVT VT
Legalized type of this argument part.
bool isUnknown() const
Returns true if we don't know any bits.
Definition KnownBits.h:64
KnownBits trunc(unsigned BitWidth) const
Return known bits for a truncation of the value we're tracking.
Definition KnownBits.h:165
KnownBits zext(unsigned BitWidth) const
Return known bits for a zero extension of the value we're tracking.
Definition KnownBits.h:176
unsigned countMaxActiveBits() const
Returns the maximum number of bits needed to represent all possible unsigned values with these known ...
Definition KnownBits.h:310
KnownBits intersectWith(const KnownBits &RHS) const
Returns KnownBits information that is known to be true for both this and RHS.
Definition KnownBits.h:325
KnownBits sext(unsigned BitWidth) const
Return known bits for a sign extension of the value we're tracking.
Definition KnownBits.h:184
unsigned countMinLeadingZeros() const
Returns the minimum number of leading zero bits.
Definition KnownBits.h:262
bool isNegative() const
Returns true if this value is known to be negative.
Definition KnownBits.h:103
static LLVM_ABI KnownBits mul(const KnownBits &LHS, const KnownBits &RHS, bool NoUndefSelfMultiply=false)
Compute known bits resulting from multiplying LHS and RHS.
bool signBitIsZeroOrNaN() const
Return true if the sign bit must be 0, ignoring the sign of nans.
Matching combinators.
This class contains a discriminated union of information about pointers in memory operands,...
LLVM_ABI bool isDereferenceable(unsigned Size, LLVMContext &C, const DataLayout &DL) const
Return true if memory region [V, V+Offset+Size) is known to be dereferenceable.
static LLVM_ABI MachinePointerInfo getStack(MachineFunction &MF, int64_t Offset, uint8_t ID=0)
Stack pointer relative access.
MachinePointerInfo getWithOffset(int64_t O) const
These are IR-level optimization flags that may be propagated to SDNodes.
void setAllowContract(bool b)
bool hasNoSignedZeros() const
This represents a list of ValueType's that has been intern'd by a SelectionDAG.
DenormalMode FP32Denormals
If this is set, neither input or output denormals are flushed for most f32 instructions.
This structure contains all information that is necessary for lowering calls.
SmallVector< ISD::InputArg, 32 > Ins
LLVM_ABI void AddToWorklist(SDNode *N)
LLVM_ABI SDValue CombineTo(SDNode *N, ArrayRef< SDValue > To, bool AddTo=true)
LLVM_ABI void CommitTargetLoweringOpt(const TargetLoweringOpt &TLO)
A convenience struct that encapsulates a DAG, and two SDValues for returning information from TargetL...