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?
787 bool ForCodeSize) const {
788 return isTypeLegal(VT.getScalarType());
789}
790
791// We don't want to shrink f64 / f32 constants.
793 EVT ScalarVT = VT.getScalarType();
794 return (ScalarVT != MVT::f32 && ScalarVT != MVT::f64);
795}
796
798 SDNode *N, ISD::LoadExtType ExtTy, EVT NewVT,
799 std::optional<unsigned> ByteOffset) const {
800 // TODO: This may be worth removing. Check regression tests for diffs.
801 if (!TargetLoweringBase::shouldReduceLoadWidth(N, ExtTy, NewVT, ByteOffset))
802 return false;
803
804 unsigned NewSize = NewVT.getStoreSizeInBits();
805
806 // If we are reducing to a 32-bit load or a smaller multi-dword load,
807 // this is always better.
808 if (NewSize >= 32)
809 return true;
810
811 EVT OldVT = N->getValueType(0);
812 unsigned OldSize = OldVT.getStoreSizeInBits();
813
815 unsigned AS = MN->getAddressSpace();
816 // Do not shrink an aligned scalar load to sub-dword.
817 // Scalar engine cannot do sub-dword loads.
818 // Do not enable for gfx1250+ even though it has sub-dword loads because
819 // this will convert:
820 // i16 = trunc (zextload i16->i32)
821 // to:
822 // i16 = (load i16)
823 // This transformation will be reversed by LowerLOAD resulting in an infinite
824 // loop. Also, tablegen already has a pattern to match zextload i16->i32, but
825 // load i16 will not be matched since there is no instruction that does it.
826 if (OldSize >= 32 && NewSize < 32 && MN->getAlign() >= Align(4) &&
830 MN->isInvariant())) &&
832 return false;
833
834 // Don't produce extloads from sub 32-bit types. SI doesn't have scalar
835 // extloads, so doing one requires using a buffer_load. In cases where we
836 // still couldn't use a scalar load, using the wider load shouldn't really
837 // hurt anything.
838
839 // If the old size already had to be an extload, there's no harm in continuing
840 // to reduce the width.
841 return (OldSize < 32);
842}
843
845 const SelectionDAG &DAG,
846 const MachineMemOperand &MMO) const {
847
848 assert(LoadTy.getSizeInBits() == CastTy.getSizeInBits());
849
850 if (LoadTy.getScalarType() == MVT::i32)
851 return false;
852
853 unsigned LScalarSize = LoadTy.getScalarSizeInBits();
854 unsigned CastScalarSize = CastTy.getScalarSizeInBits();
855
856 if ((LScalarSize >= CastScalarSize) && (CastScalarSize < 32))
857 return false;
858
859 unsigned Fast = 0;
861 CastTy, MMO, &Fast) &&
862 Fast;
863}
864
865// SI+ has instructions for cttz / ctlz for 32-bit values. This is probably also
866// profitable with the expansion for 64-bit since it's generally good to
867// speculate things.
869 return true;
870}
871
873 return true;
874}
875
877 switch (N->getOpcode()) {
878 case ISD::EntryToken:
879 case ISD::TokenFactor:
880 return true;
882 unsigned IntrID = N->getConstantOperandVal(0);
884 }
886 unsigned IntrID = N->getConstantOperandVal(1);
888 }
889 case ISD::LOAD:
890 if (cast<LoadSDNode>(N)->getMemOperand()->getAddrSpace() ==
892 return true;
893 return false;
894 case AMDGPUISD::SETCC: // ballot-style instruction
895 return true;
896 }
897 return false;
898}
899
901 SDValue Op, SelectionDAG &DAG, bool LegalOperations, bool ForCodeSize,
902 NegatibleCost &Cost, unsigned Depth) const {
903
904 switch (Op.getOpcode()) {
905 case ISD::FMA:
906 case ISD::FMAD: {
907 // Negating a fma is not free if it has users without source mods.
908 if (!allUsesHaveSourceMods(Op.getNode()))
909 return SDValue();
910 break;
911 }
912 case AMDGPUISD::RCP: {
913 SDValue Src = Op.getOperand(0);
914 EVT VT = Op.getValueType();
915 SDLoc SL(Op);
916
917 SDValue NegSrc = getNegatedExpression(Src, DAG, LegalOperations,
918 ForCodeSize, Cost, Depth + 1);
919 if (NegSrc)
920 return DAG.getNode(AMDGPUISD::RCP, SL, VT, NegSrc, Op->getFlags());
921 return SDValue();
922 }
923 default:
924 break;
925 }
926
927 return TargetLowering::getNegatedExpression(Op, DAG, LegalOperations,
928 ForCodeSize, Cost, Depth);
929}
930
931//===---------------------------------------------------------------------===//
932// Target Properties
933//===---------------------------------------------------------------------===//
934
937
938 // Packed operations do not have a fabs modifier.
939 // Report this based on the end legalized type.
940 return VT == MVT::f32 || VT == MVT::f64 || VT == MVT::f16 || VT == MVT::bf16;
941}
942
945 // Report this based on the end legalized type.
946 VT = VT.getScalarType();
947 return VT == MVT::f32 || VT == MVT::f64 || VT == MVT::f16 || VT == MVT::bf16;
948}
949
951 unsigned NumElem,
952 unsigned AS) const {
953 return true;
954}
955
957 // There are few operations which truly have vector input operands. Any vector
958 // operation is going to involve operations on each component, and a
959 // build_vector will be a copy per element, so it always makes sense to use a
960 // build_vector input in place of the extracted element to avoid a copy into a
961 // super register.
962 //
963 // We should probably only do this if all users are extracts only, but this
964 // should be the common case.
965 return true;
966}
967
969 // Truncate is just accessing a subregister.
970
971 unsigned SrcSize = Source.getSizeInBits();
972 unsigned DestSize = Dest.getSizeInBits();
973
974 return DestSize < SrcSize && DestSize % 32 == 0 ;
975}
976
978 // Truncate is just accessing a subregister.
979
980 unsigned SrcSize = Source->getScalarSizeInBits();
981 unsigned DestSize = Dest->getScalarSizeInBits();
982
983 if (DestSize== 16 && Subtarget->has16BitInsts())
984 return SrcSize >= 32;
985
986 return DestSize < SrcSize && DestSize % 32 == 0;
987}
988
990 unsigned SrcSize = Src->getScalarSizeInBits();
991 unsigned DestSize = Dest->getScalarSizeInBits();
992
993 if (SrcSize == 16 && Subtarget->has16BitInsts())
994 return DestSize >= 32;
995
996 return SrcSize == 32 && DestSize == 64;
997}
998
1000 // Any register load of a 64-bit value really requires 2 32-bit moves. For all
1001 // practical purposes, the extra mov 0 to load a 64-bit is free. As used,
1002 // this will enable reducing 64-bit operations the 32-bit, which is always
1003 // good.
1004
1005 if (Src == MVT::i16)
1006 return Dest == MVT::i32 ||Dest == MVT::i64 ;
1007
1008 return Src == MVT::i32 && Dest == MVT::i64;
1009}
1010
1012 EVT DestVT) const {
1013 switch (N->getOpcode()) {
1014 case ISD::ABS:
1015 case ISD::ADD:
1016 case ISD::SUB:
1017 case ISD::SHL:
1018 case ISD::SRL:
1019 case ISD::SRA:
1020 case ISD::AND:
1021 case ISD::OR:
1022 case ISD::XOR:
1023 case ISD::MUL:
1024 case ISD::SETCC:
1025 case ISD::SELECT:
1026 case ISD::SMIN:
1027 case ISD::SMAX:
1028 case ISD::UMIN:
1029 case ISD::UMAX:
1030 case ISD::USUBSAT:
1031 case ISD::UADDSAT:
1032 if (isTypeLegal(MVT::i16) &&
1033 (!DestVT.isVector() ||
1034 !isOperationLegal(ISD::ADD, MVT::v2i16))) { // Check if VOP3P
1035 // Don't narrow back down to i16 if promoted to i32 already.
1036 if (!N->isDivergent() && DestVT.isInteger() &&
1037 DestVT.getScalarSizeInBits() > 1 &&
1038 DestVT.getScalarSizeInBits() <= 16 &&
1039 SrcVT.getScalarSizeInBits() > 16) {
1040 return false;
1041 }
1042 }
1043 return true;
1044 default:
1045 break;
1046 }
1047
1048 // There aren't really 64-bit registers, but pairs of 32-bit ones and only a
1049 // limited number of native 64-bit operations. Shrinking an operation to fit
1050 // in a single 32-bit register should always be helpful. As currently used,
1051 // this is much less general than the name suggests, and is only used in
1052 // places trying to reduce the sizes of loads. Shrinking loads to < 32-bits is
1053 // not profitable, and may actually be harmful.
1054 if (isa<LoadSDNode>(N))
1055 return SrcVT.getSizeInBits() > 32 && DestVT.getSizeInBits() == 32;
1056
1057 return true;
1058}
1059
1061 const SDNode* N, CombineLevel Level) const {
1062 assert((N->getOpcode() == ISD::SHL || N->getOpcode() == ISD::SRA ||
1063 N->getOpcode() == ISD::SRL) &&
1064 "Expected shift op");
1065
1066 SDValue ShiftLHS = N->getOperand(0);
1067 if (!ShiftLHS->hasOneUse())
1068 return false;
1069
1070 if (ShiftLHS.getOpcode() == ISD::SIGN_EXTEND &&
1071 !ShiftLHS.getOperand(0)->hasOneUse())
1072 return false;
1073
1074 // Always commute pre-type legalization and right shifts.
1075 // We're looking for shl(or(x,y),z) patterns.
1077 N->getOpcode() != ISD::SHL || N->getOperand(0).getOpcode() != ISD::OR)
1078 return true;
1079
1080 // If only user is a i32 right-shift, then don't destroy a BFE pattern.
1081 if (N->getValueType(0) == MVT::i32 && N->hasOneUse() &&
1082 (N->user_begin()->getOpcode() == ISD::SRA ||
1083 N->user_begin()->getOpcode() == ISD::SRL))
1084 return false;
1085
1086 // Don't destroy or(shl(load_zext(),c), load_zext()) patterns.
1087 auto IsShiftAndLoad = [](SDValue LHS, SDValue RHS) {
1088 if (LHS.getOpcode() != ISD::SHL)
1089 return false;
1090 auto *RHSLd = dyn_cast<LoadSDNode>(RHS);
1091 auto *LHS0 = dyn_cast<LoadSDNode>(LHS.getOperand(0));
1092 auto *LHS1 = dyn_cast<ConstantSDNode>(LHS.getOperand(1));
1093 return LHS0 && LHS1 && RHSLd && LHS0->getExtensionType() == ISD::ZEXTLOAD &&
1094 LHS1->getAPIntValue() == LHS0->getMemoryVT().getScalarSizeInBits() &&
1095 RHSLd->getExtensionType() == ISD::ZEXTLOAD;
1096 };
1097 SDValue LHS = N->getOperand(0).getOperand(0);
1098 SDValue RHS = N->getOperand(0).getOperand(1);
1099 return !(IsShiftAndLoad(LHS, RHS) || IsShiftAndLoad(RHS, LHS));
1100}
1101
1102//===---------------------------------------------------------------------===//
1103// TargetLowering Callbacks
1104//===---------------------------------------------------------------------===//
1105
1107 bool IsVarArg) {
1108 switch (CC) {
1116 return CC_AMDGPU;
1119 return CC_AMDGPU_CS_CHAIN;
1120 case CallingConv::C:
1121 case CallingConv::Fast:
1122 case CallingConv::Cold:
1123 return CC_AMDGPU_Func;
1126 return CC_SI_Gfx;
1129 default:
1130 reportFatalUsageError("unsupported calling convention for call");
1131 }
1132}
1133
1135 bool IsVarArg) {
1136 switch (CC) {
1139 llvm_unreachable("kernels should not be handled here");
1149 return RetCC_SI_Shader;
1152 return RetCC_SI_Gfx;
1153 case CallingConv::C:
1154 case CallingConv::Fast:
1155 case CallingConv::Cold:
1156 return RetCC_AMDGPU_Func;
1157 default:
1158 reportFatalUsageError("unsupported calling convention");
1159 }
1160}
1161
1162/// The SelectionDAGBuilder will automatically promote function arguments
1163/// with illegal types. However, this does not work for the AMDGPU targets
1164/// since the function arguments are stored in memory as these illegal types.
1165/// In order to handle this properly we need to get the original types sizes
1166/// from the LLVM IR Function and fixup the ISD:InputArg values before
1167/// passing them to AnalyzeFormalArguments()
1168
1169/// When the SelectionDAGBuilder computes the Ins, it takes care of splitting
1170/// input values across multiple registers. Each item in the Ins array
1171/// represents a single value that will be stored in registers. Ins[x].VT is
1172/// the value type of the value that will be stored in the register, so
1173/// whatever SDNode we lower the argument to needs to be this type.
1174///
1175/// In order to correctly lower the arguments we need to know the size of each
1176/// argument. Since Ins[x].VT gives us the size of the register that will
1177/// hold the value, we need to look at Ins[x].ArgVT to see the 'real' type
1178/// for the original function argument so that we can deduce the correct memory
1179/// type to use for Ins[x]. In most cases the correct memory type will be
1180/// Ins[x].ArgVT. However, this will not always be the case. If, for example,
1181/// we have a kernel argument of type v8i8, this argument will be split into
1182/// 8 parts and each part will be represented by its own item in the Ins array.
1183/// For each part the Ins[x].ArgVT will be the v8i8, which is the full type of
1184/// the argument before it was split. From this, we deduce that the memory type
1185/// for each individual part is i8. We pass the memory type as LocVT to the
1186/// calling convention analysis function and the register type (Ins[x].VT) as
1187/// the ValVT.
1189 CCState &State,
1190 const SmallVectorImpl<ISD::InputArg> &Ins) const {
1191 const MachineFunction &MF = State.getMachineFunction();
1192 const Function &Fn = MF.getFunction();
1193 LLVMContext &Ctx = Fn.getContext();
1194 const unsigned ExplicitOffset = Subtarget->getExplicitKernelArgOffset();
1196
1197 Align MaxAlign = Align(1);
1198 uint64_t ExplicitArgOffset = 0;
1199 const DataLayout &DL = Fn.getDataLayout();
1200
1201 unsigned InIndex = 0;
1202
1203 for (const Argument &Arg : Fn.args()) {
1204 const bool IsByRef = Arg.hasByRefAttr();
1205 Type *BaseArgTy = Arg.getType();
1206 Type *MemArgTy = IsByRef ? Arg.getParamByRefType() : BaseArgTy;
1207 Align Alignment = DL.getValueOrABITypeAlignment(
1208 IsByRef ? Arg.getParamAlign() : std::nullopt, MemArgTy);
1209 MaxAlign = std::max(Alignment, MaxAlign);
1210 uint64_t AllocSize = DL.getTypeAllocSize(MemArgTy);
1211
1212 uint64_t ArgOffset = alignTo(ExplicitArgOffset, Alignment) + ExplicitOffset;
1213 ExplicitArgOffset = alignTo(ExplicitArgOffset, Alignment) + AllocSize;
1214
1215 // We're basically throwing away everything passed into us and starting over
1216 // to get accurate in-memory offsets. The "PartOffset" is completely useless
1217 // to us as computed in Ins.
1218 //
1219 // We also need to figure out what type legalization is trying to do to get
1220 // the correct memory offsets.
1221
1222 SmallVector<EVT, 16> ValueVTs;
1224 ComputeValueVTs(*this, DL, BaseArgTy, ValueVTs, /*MemVTs=*/nullptr,
1225 &Offsets, ArgOffset);
1226
1227 for (unsigned Value = 0, NumValues = ValueVTs.size();
1228 Value != NumValues; ++Value) {
1229 uint64_t BasePartOffset = Offsets[Value];
1230
1231 EVT ArgVT = ValueVTs[Value];
1232 EVT MemVT = ArgVT;
1233 MVT RegisterVT = getRegisterTypeForCallingConv(Ctx, CC, ArgVT);
1234 unsigned NumRegs = getNumRegistersForCallingConv(Ctx, CC, ArgVT);
1235
1236 if (NumRegs == 1) {
1237 // This argument is not split, so the IR type is the memory type.
1238 if (ArgVT.isExtended()) {
1239 // We have an extended type, like i24, so we should just use the
1240 // register type.
1241 MemVT = RegisterVT;
1242 } else {
1243 MemVT = ArgVT;
1244 }
1245 } else if (ArgVT.isVector() && RegisterVT.isVector() &&
1246 ArgVT.getScalarType() == RegisterVT.getScalarType()) {
1247 assert(ArgVT.getVectorNumElements() > RegisterVT.getVectorNumElements());
1248 // We have a vector value which has been split into a vector with
1249 // the same scalar type, but fewer elements. This should handle
1250 // all the floating-point vector types.
1251 MemVT = RegisterVT;
1252 } else if (ArgVT.isVector() &&
1253 ArgVT.getVectorNumElements() == NumRegs) {
1254 // This arg has been split so that each element is stored in a separate
1255 // register.
1256 MemVT = ArgVT.getScalarType();
1257 } else if (ArgVT.isExtended()) {
1258 // We have an extended type, like i65.
1259 MemVT = RegisterVT;
1260 } else {
1261 unsigned MemoryBits = ArgVT.getStoreSizeInBits() / NumRegs;
1262 assert(ArgVT.getStoreSizeInBits() % NumRegs == 0);
1263 if (RegisterVT.isInteger()) {
1264 MemVT = EVT::getIntegerVT(State.getContext(), MemoryBits);
1265 } else if (RegisterVT.isVector()) {
1266 assert(!RegisterVT.getScalarType().isFloatingPoint());
1267 unsigned NumElements = RegisterVT.getVectorNumElements();
1268 assert(MemoryBits % NumElements == 0);
1269 // This vector type has been split into another vector type with
1270 // a different elements size.
1271 EVT ScalarVT = EVT::getIntegerVT(State.getContext(),
1272 MemoryBits / NumElements);
1273 MemVT = EVT::getVectorVT(State.getContext(), ScalarVT, NumElements);
1274 } else {
1275 llvm_unreachable("cannot deduce memory type.");
1276 }
1277 }
1278
1279 // Convert one element vectors to scalar.
1280 if (MemVT.isVector() && MemVT.getVectorNumElements() == 1)
1281 MemVT = MemVT.getScalarType();
1282
1283 // Round up vec3/vec5 argument.
1284 if (MemVT.isVector() && !MemVT.isPow2VectorType()) {
1285 MemVT = MemVT.getPow2VectorType(State.getContext());
1286 } else if (!MemVT.isSimple() && !MemVT.isVector()) {
1287 MemVT = MemVT.getRoundIntegerType(State.getContext());
1288 }
1289
1290 unsigned PartOffset = 0;
1291 for (unsigned i = 0; i != NumRegs; ++i) {
1292 State.addLoc(CCValAssign::getCustomMem(InIndex++, RegisterVT,
1293 BasePartOffset + PartOffset,
1294 MemVT.getSimpleVT(),
1296 PartOffset += MemVT.getStoreSize();
1297 }
1298 }
1299 }
1300}
1301
1303 SDValue Chain, CallingConv::ID CallConv,
1304 bool isVarArg,
1306 const SmallVectorImpl<SDValue> &OutVals,
1307 const SDLoc &DL, SelectionDAG &DAG) const {
1308 // FIXME: Fails for r600 tests
1309 //assert(!isVarArg && Outs.empty() && OutVals.empty() &&
1310 // "wave terminate should not have return values");
1311 return DAG.getNode(AMDGPUISD::ENDPGM, DL, MVT::Other, Chain);
1312}
1313
1314//===---------------------------------------------------------------------===//
1315// Target specific lowering
1316//===---------------------------------------------------------------------===//
1317
1318/// Selects the correct CCAssignFn for a given CallingConvention value.
1323
1328
1330 SelectionDAG &DAG,
1331 MachineFrameInfo &MFI,
1332 int ClobberedFI) const {
1333 SmallVector<SDValue, 8> ArgChains;
1334 int64_t FirstByte = MFI.getObjectOffset(ClobberedFI);
1335 int64_t LastByte = FirstByte + MFI.getObjectSize(ClobberedFI) - 1;
1336
1337 // Include the original chain at the beginning of the list. When this is
1338 // used by target LowerCall hooks, this helps legalize find the
1339 // CALLSEQ_BEGIN node.
1340 ArgChains.push_back(Chain);
1341
1342 // Add a chain value for each stack argument corresponding
1343 for (SDNode *U : DAG.getEntryNode().getNode()->users()) {
1344 if (LoadSDNode *L = dyn_cast<LoadSDNode>(U)) {
1345 if (FrameIndexSDNode *FI = dyn_cast<FrameIndexSDNode>(L->getBasePtr())) {
1346 if (FI->getIndex() < 0) {
1347 int64_t InFirstByte = MFI.getObjectOffset(FI->getIndex());
1348 int64_t InLastByte = InFirstByte;
1349 InLastByte += MFI.getObjectSize(FI->getIndex()) - 1;
1350
1351 if ((InFirstByte <= FirstByte && FirstByte <= InLastByte) ||
1352 (FirstByte <= InFirstByte && InFirstByte <= LastByte))
1353 ArgChains.push_back(SDValue(L, 1));
1354 }
1355 }
1356 }
1357 }
1358
1359 // Build a tokenfactor for all the chains.
1360 return DAG.getNode(ISD::TokenFactor, SDLoc(Chain), MVT::Other, ArgChains);
1361}
1362
1365 StringRef Reason) const {
1366 SDValue Callee = CLI.Callee;
1367 SelectionDAG &DAG = CLI.DAG;
1368
1369 const Function &Fn = DAG.getMachineFunction().getFunction();
1370
1371 StringRef FuncName("<unknown>");
1372
1374 FuncName = G->getSymbol();
1375 else if (const GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee))
1376 FuncName = G->getGlobal()->getName();
1377
1378 DAG.getContext()->diagnose(
1379 DiagnosticInfoUnsupported(Fn, Reason + FuncName, CLI.DL.getDebugLoc()));
1380
1381 if (!CLI.IsTailCall) {
1382 for (ISD::InputArg &Arg : CLI.Ins)
1383 InVals.push_back(DAG.getPOISON(Arg.VT));
1384 }
1385
1386 // FIXME: Hack because R600 doesn't handle callseq pseudos yet.
1387 if (getTargetMachine().getTargetTriple().getArch() == Triple::r600)
1388 return CLI.Chain;
1389
1390 SDValue Chain = DAG.getCALLSEQ_START(CLI.Chain, 0, 0, CLI.DL);
1391 return DAG.getCALLSEQ_END(Chain, 0, 0, /*InGlue=*/SDValue(), CLI.DL);
1392}
1393
1395 SmallVectorImpl<SDValue> &InVals) const {
1396 return lowerUnhandledCall(CLI, InVals, "unsupported call to function ");
1397}
1398
1400 SelectionDAG &DAG) const {
1401 const Function &Fn = DAG.getMachineFunction().getFunction();
1402
1404 Fn, "unsupported dynamic alloca", SDLoc(Op).getDebugLoc()));
1405 auto Ops = {DAG.getConstant(0, SDLoc(), Op.getValueType()), Op.getOperand(0)};
1406 return DAG.getMergeValues(Ops, SDLoc());
1407}
1408
1410 SelectionDAG &DAG) const {
1411 switch (Op.getOpcode()) {
1412 default:
1413 Op->print(errs(), &DAG);
1414 llvm_unreachable("Custom lowering code for this "
1415 "instruction is not implemented yet!");
1416 break;
1418 case ISD::CONCAT_VECTORS: return LowerCONCAT_VECTORS(Op, DAG);
1420 case ISD::UDIVREM: return LowerUDIVREM(Op, DAG);
1421 case ISD::SDIVREM:
1422 return LowerSDIVREM(Op, DAG);
1423 case ISD::FCEIL: return LowerFCEIL(Op, DAG);
1424 case ISD::FTRUNC: return LowerFTRUNC(Op, DAG);
1425 case ISD::FRINT: return LowerFRINT(Op, DAG);
1426 case ISD::FNEARBYINT: return LowerFNEARBYINT(Op, DAG);
1427 case ISD::FROUNDEVEN:
1428 return LowerFROUNDEVEN(Op, DAG);
1429 case ISD::FROUND: return LowerFROUND(Op, DAG);
1430 case ISD::FFLOOR: return LowerFFLOOR(Op, DAG);
1431 case ISD::FLOG2:
1432 return LowerFLOG2(Op, DAG);
1433 case ISD::FLOG:
1434 case ISD::FLOG10:
1435 return LowerFLOGCommon(Op, DAG);
1436 case ISD::FEXP:
1437 case ISD::FEXP10:
1438 return lowerFEXP(Op, DAG);
1439 case ISD::FEXP2:
1440 return lowerFEXP2(Op, DAG);
1441 case ISD::FPOW:
1442 return lowerFPOW(Op, DAG);
1443 case ISD::SINT_TO_FP: return LowerSINT_TO_FP(Op, DAG);
1444 case ISD::UINT_TO_FP: return LowerUINT_TO_FP(Op, DAG);
1445 case ISD::FP_TO_FP16: return LowerFP_TO_FP16(Op, DAG);
1446 case ISD::FP_TO_SINT:
1447 case ISD::FP_TO_UINT:
1448 return LowerFP_TO_INT(Op, DAG);
1451 return LowerFP_TO_INT_SAT(Op, DAG);
1452 case ISD::CTTZ:
1454 case ISD::CTLZ:
1456 return LowerCTLZ_CTTZ(Op, DAG);
1457 case ISD::CTLS:
1458 return LowerCTLS(Op, DAG);
1460 }
1461 return Op;
1462}
1463
1466 SelectionDAG &DAG) const {
1467 switch (N->getOpcode()) {
1469 // Different parts of legalization seem to interpret which type of
1470 // sign_extend_inreg is the one to check for custom lowering. The extended
1471 // from type is what really matters, but some places check for custom
1472 // lowering of the result type. This results in trying to use
1473 // ReplaceNodeResults to sext_in_reg to an illegal type, so we'll just do
1474 // nothing here and let the illegal result integer be handled normally.
1475 return;
1476 case ISD::FLOG2:
1477 if (SDValue Lowered = LowerFLOG2(SDValue(N, 0), DAG))
1478 Results.push_back(Lowered);
1479 return;
1480 case ISD::FLOG:
1481 case ISD::FLOG10:
1482 if (SDValue Lowered = LowerFLOGCommon(SDValue(N, 0), DAG))
1483 Results.push_back(Lowered);
1484 return;
1485 case ISD::FEXP2:
1486 if (SDValue Lowered = lowerFEXP2(SDValue(N, 0), DAG))
1487 Results.push_back(Lowered);
1488 return;
1489 case ISD::FEXP:
1490 case ISD::FEXP10:
1491 if (SDValue Lowered = lowerFEXP(SDValue(N, 0), DAG))
1492 Results.push_back(Lowered);
1493 return;
1494 case ISD::CTLZ:
1496 if (auto Lowered = lowerCTLZResults(SDValue(N, 0u), DAG))
1497 Results.push_back(Lowered);
1498 return;
1499 default:
1500 return;
1501 }
1502}
1503
1505 SelectionDAG &DAG) const {
1507 SDLoc SL(Op);
1508 EVT VT = Op.getValueType();
1509 return DAG.getTargetBlockAddress(BA->getBlockAddress(), VT, BA->getOffset(),
1510 BA->getTargetFlags());
1511}
1512
1514 SDValue Op,
1515 SelectionDAG &DAG) const {
1516
1517 const DataLayout &DL = DAG.getDataLayout();
1519 const GlobalValue *GV = G->getGlobal();
1520
1521 if (G->getAddressSpace() == AMDGPUAS::BARRIER) {
1522 const GlobalVariable *GVar = cast<GlobalVariable>(GV);
1523
1524 if (!AMDGPU::isNamedBarrier(*GVar)) {
1525 const Function &Fn = DAG.getMachineFunction().getFunction();
1527 Fn, "unsupported use of BARRIER address space",
1529 return DAG.getPOISON(Op.getValueType());
1530 }
1531
1532 unsigned Offset = MFI->allocateBarrierGlobal(DL, *cast<GlobalVariable>(GV));
1533 return DAG.getConstant(Offset, SDLoc(Op), Op.getValueType());
1534 }
1535
1536 if (!MFI->isModuleEntryFunction()) {
1537 if (std::optional<uint32_t> Address =
1540 return DAG.getConstant(*Address, SDLoc(Op), Op.getValueType());
1541 }
1542 }
1543
1544 if (G->getAddressSpace() == AMDGPUAS::LOCAL_ADDRESS ||
1545 G->getAddressSpace() == AMDGPUAS::REGION_ADDRESS) {
1546 if (!MFI->isModuleEntryFunction() &&
1547 GV->getName() != "llvm.amdgcn.module.lds") {
1548 SDLoc DL(Op);
1549 const Function &Fn = DAG.getMachineFunction().getFunction();
1551 Fn, "local memory global used by non-kernel function",
1552 DL.getDebugLoc(), DS_Warning));
1553
1554 // We currently don't have a way to correctly allocate LDS objects that
1555 // aren't directly associated with a kernel. We do force inlining of
1556 // functions that use local objects. However, if these dead functions are
1557 // not eliminated, we don't want a compile time error. Just emit a warning
1558 // and a trap, since there should be no callable path here.
1559 SDValue Trap = DAG.getNode(ISD::TRAP, DL, MVT::Other, DAG.getEntryNode());
1560 SDValue OutputChain = DAG.getNode(ISD::TokenFactor, DL, MVT::Other,
1561 Trap, DAG.getRoot());
1562 DAG.setRoot(OutputChain);
1563 return DAG.getPOISON(Op.getValueType());
1564 }
1565
1566 // TODO: We could emit code to handle the initialization somewhere.
1567 // We ignore the initializer for now and legalize it to allow selection.
1568 // The initializer will anyway get errored out during assembly emission.
1569 unsigned Offset = MFI->allocateLDSGlobal(DL, *cast<GlobalVariable>(GV));
1570 // A constant byte offset (e.g. from a GEP into an array of named barriers)
1571 // folds directly into the allocated LDS address.
1572 return DAG.getConstant(Offset + G->getOffset(), SDLoc(Op),
1573 Op.getValueType());
1574 }
1575 return SDValue();
1576}
1577
1579 SelectionDAG &DAG) const {
1581 SDLoc SL(Op);
1582
1583 EVT VT = Op.getValueType();
1584 if (VT.getVectorElementType().getSizeInBits() < 32) {
1585 unsigned OpBitSize = Op.getOperand(0).getValueType().getSizeInBits();
1586 if (OpBitSize >= 32 && OpBitSize % 32 == 0) {
1587 unsigned NewNumElt = OpBitSize / 32;
1588 EVT NewEltVT = (NewNumElt == 1) ? MVT::i32
1590 MVT::i32, NewNumElt);
1591 for (const SDUse &U : Op->ops()) {
1592 SDValue In = U.get();
1593 SDValue NewIn = DAG.getNode(ISD::BITCAST, SL, NewEltVT, In);
1594 if (NewNumElt > 1)
1595 DAG.ExtractVectorElements(NewIn, Args);
1596 else
1597 Args.push_back(NewIn);
1598 }
1599
1600 EVT NewVT = EVT::getVectorVT(*DAG.getContext(), MVT::i32,
1601 NewNumElt * Op.getNumOperands());
1602 SDValue BV = DAG.getBuildVector(NewVT, SL, Args);
1603 return DAG.getNode(ISD::BITCAST, SL, VT, BV);
1604 }
1605 }
1606
1607 for (const SDUse &U : Op->ops())
1608 DAG.ExtractVectorElements(U.get(), Args);
1609
1610 return DAG.getBuildVector(Op.getValueType(), SL, Args);
1611}
1612
1614 SelectionDAG &DAG) const {
1615 SDLoc SL(Op);
1617 unsigned Start = Op.getConstantOperandVal(1);
1618 EVT VT = Op.getValueType();
1619 EVT SrcVT = Op.getOperand(0).getValueType();
1620
1621 if (VT.getScalarSizeInBits() == 16 && Start % 2 == 0) {
1622 unsigned NumElt = VT.getVectorNumElements();
1623 unsigned NumSrcElt = SrcVT.getVectorNumElements();
1624 assert(NumElt % 2 == 0 && NumSrcElt % 2 == 0 && "expect legal types");
1625
1626 // Extract 32-bit registers at a time.
1627 EVT NewSrcVT = EVT::getVectorVT(*DAG.getContext(), MVT::i32, NumSrcElt / 2);
1628 EVT NewVT = NumElt == 2
1629 ? MVT::i32
1630 : EVT::getVectorVT(*DAG.getContext(), MVT::i32, NumElt / 2);
1631 SDValue Tmp = DAG.getNode(ISD::BITCAST, SL, NewSrcVT, Op.getOperand(0));
1632
1633 DAG.ExtractVectorElements(Tmp, Args, Start / 2, NumElt / 2);
1634 if (NumElt == 2)
1635 Tmp = Args[0];
1636 else
1637 Tmp = DAG.getBuildVector(NewVT, SL, Args);
1638
1639 return DAG.getNode(ISD::BITCAST, SL, VT, Tmp);
1640 }
1641
1642 DAG.ExtractVectorElements(Op.getOperand(0), Args, Start,
1644
1645 return DAG.getBuildVector(Op.getValueType(), SL, Args);
1646}
1647
1648// TODO: Handle fabs too
1650 if (Val.getOpcode() == ISD::FNEG)
1651 return Val.getOperand(0);
1652
1653 return Val;
1654}
1655
1656// SelectionDAG twin of AMDGPUCombinerHelper::canIgnoreLegacyMinMaxTies.
1658 SDNodeFlags Flags, SDValue LHS,
1659 SDValue RHS) {
1660 return Flags.hasNoSignedZeros() || DAG.isKnownNeverLogicalZero(LHS) ||
1662}
1663
1665 const SDLoc &DL, EVT VT, SDValue LHS, SDValue RHS, SDValue True,
1666 SDValue False, SDValue CC, SDNodeFlags Flags, DAGCombinerInfo &DCI) const {
1667 SelectionDAG &DAG = DCI.DAG;
1668 ISD::CondCode CCOpcode = cast<CondCodeSDNode>(CC)->get();
1669 assert(CCOpcode != ISD::SETCC_INVALID && "Invalid setcc condcode!");
1670
1671 switch (CCOpcode) {
1672 case ISD::SETOLE:
1673 case ISD::SETOLT:
1674 case ISD::SETLE:
1675 case ISD::SETLT:
1676 case ISD::SETOGE:
1677 case ISD::SETOGT:
1678 case ISD::SETGE:
1679 case ISD::SETGT:
1680 // Only do this after legalization to avoid interfering with other combines
1681 // which might occur.
1683 !DCI.isCalledByLegalizer())
1684 return SDValue();
1685 break;
1686 default:
1687 break;
1688 }
1689
1690 // Canonicalize so the select returns the compare's LHS on a true predicate.
1691 if (LHS != True)
1692 CCOpcode = ISD::getSetCCInverse(CCOpcode, VT);
1693
1694 unsigned Opc;
1695 bool Swap; // Emit (rhs, lhs) instead of (lhs, rhs).
1696 switch (CCOpcode) {
1697 case ISD::SETOLT:
1698 case ISD::SETLT:
1699 case ISD::SETOLE:
1700 Opc = AMDGPUISD::FMIN_LEGACY;
1701 Swap = false;
1702 break;
1703 case ISD::SETULE:
1704 case ISD::SETLE:
1705 case ISD::SETULT:
1706 Opc = AMDGPUISD::FMIN_LEGACY;
1707 Swap = true;
1708 break;
1709 case ISD::SETOGE:
1710 case ISD::SETGE:
1711 case ISD::SETOGT:
1712 Opc = AMDGPUISD::FMAX_LEGACY;
1713 Swap = false;
1714 break;
1715 case ISD::SETUGT:
1716 case ISD::SETGT:
1717 case ISD::SETUGE:
1718 Opc = AMDGPUISD::FMAX_LEGACY;
1719 Swap = true;
1720 break;
1721 default:
1722 return SDValue();
1723 }
1724
1725 // For these predicates the NaN-correct operand order is the signed zero
1726 // tie-incorrect one, so the fold needs the tie to be unobservable.
1727 if ((CCOpcode == ISD::SETOLE || CCOpcode == ISD::SETULT ||
1728 CCOpcode == ISD::SETOGT || CCOpcode == ISD::SETUGE) &&
1729 !canIgnoreLegacyMinMaxTies(DAG, Flags, LHS, RHS))
1730 return SDValue();
1731
1732 if (Swap)
1733 std::swap(LHS, RHS);
1734 return DAG.getNode(Opc, DL, VT, LHS, RHS, Flags);
1735}
1736
1737/// Generate Min/Max node
1739 const SDLoc &DL, EVT VT, SDValue LHS, SDValue RHS, SDValue True,
1740 SDValue False, SDValue CC, SDNodeFlags Flags, DAGCombinerInfo &DCI) const {
1741 if ((LHS == True && RHS == False) || (LHS == False && RHS == True))
1742 return combineFMinMaxLegacyImpl(DL, VT, LHS, RHS, True, False, CC, Flags,
1743 DCI);
1744
1745 SelectionDAG &DAG = DCI.DAG;
1746
1747 // If we can't directly match this, try to see if we can fold an fneg to
1748 // match.
1749
1752 SDValue NegTrue = peekFNeg(True);
1753
1754 // Undo the combine foldFreeOpFromSelect does if it helps us match the
1755 // fmin/fmax.
1756 //
1757 // select (fcmp olt (lhs, K)), (fneg lhs), -K
1758 // -> fneg (fmin_legacy lhs, K)
1759 //
1760 // TODO: Use getNegatedExpression
1761 if (LHS == NegTrue && CFalse && CRHS) {
1762 APFloat NegRHS = neg(CRHS->getValueAPF());
1763 if (NegRHS == CFalse->getValueAPF()) {
1764 SDValue Combined = combineFMinMaxLegacyImpl(DL, VT, LHS, RHS, NegTrue,
1765 False, CC, Flags, DCI);
1766 if (Combined)
1767 return DAG.getNode(ISD::FNEG, DL, VT, Combined);
1768 return SDValue();
1769 }
1770 }
1771
1772 return SDValue();
1773}
1774
1775std::pair<SDValue, SDValue>
1777 SDLoc SL(Op);
1778
1779 SDValue Vec = DAG.getNode(ISD::BITCAST, SL, MVT::v2i32, Op);
1780
1781 const SDValue Zero = DAG.getConstant(0, SL, MVT::i32);
1782 const SDValue One = DAG.getConstant(1, SL, MVT::i32);
1783
1784 SDValue Lo = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, SL, MVT::i32, Vec, Zero);
1785 SDValue Hi = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, SL, MVT::i32, Vec, One);
1786
1787 return std::pair(Lo, Hi);
1788}
1789
1791 SDLoc SL(Op);
1792
1793 SDValue Vec = DAG.getNode(ISD::BITCAST, SL, MVT::v2i32, Op);
1794 const SDValue One = DAG.getConstant(1, SL, MVT::i32);
1795 return DAG.getNode(ISD::EXTRACT_VECTOR_ELT, SL, MVT::i32, Vec, One);
1796}
1797
1798// Split a vector type into two parts. The first part is a power of two vector.
1799// The second part is whatever is left over, and is a scalar if it would
1800// otherwise be a 1-vector.
1801std::pair<EVT, EVT>
1803 EVT LoVT, HiVT;
1804 EVT EltVT = VT.getVectorElementType();
1805 unsigned NumElts = VT.getVectorNumElements();
1806 unsigned LoNumElts = PowerOf2Ceil((NumElts + 1) / 2);
1807 LoVT = EVT::getVectorVT(*DAG.getContext(), EltVT, LoNumElts);
1808 HiVT = NumElts - LoNumElts == 1
1809 ? EltVT
1810 : EVT::getVectorVT(*DAG.getContext(), EltVT, NumElts - LoNumElts);
1811 return std::pair(LoVT, HiVT);
1812}
1813
1814// Split a vector value into two parts of types LoVT and HiVT. HiVT could be
1815// scalar.
1816std::pair<SDValue, SDValue>
1818 const EVT &LoVT, const EVT &HiVT,
1819 SelectionDAG &DAG) const {
1820 EVT VT = N.getValueType();
1822 (HiVT.isVector() ? HiVT.getVectorNumElements() : 1) <=
1823 VT.getVectorNumElements() &&
1824 "More vector elements requested than available!");
1826 DAG.getVectorIdxConstant(0, DL));
1827
1828 unsigned LoNumElts = LoVT.getVectorNumElements();
1829
1830 if (HiVT.isVector()) {
1831 unsigned HiNumElts = HiVT.getVectorNumElements();
1832 if ((VT.getVectorNumElements() % HiNumElts) == 0) {
1833 // Avoid creating an extract_subvector with an index that isn't a multiple
1834 // of the result type.
1836 DAG.getConstant(LoNumElts, DL, MVT::i32));
1837 return {Lo, Hi};
1838 }
1839
1841 DAG.ExtractVectorElements(N, Elts, /*Start=*/LoNumElts,
1842 /*Count=*/HiNumElts);
1843 SDValue Hi = DAG.getBuildVector(HiVT, DL, Elts);
1844 return {Lo, Hi};
1845 }
1846
1848 DAG.getVectorIdxConstant(LoNumElts, DL));
1849 return {Lo, Hi};
1850}
1851
1853 SelectionDAG &DAG) const {
1855 EVT VT = Op.getValueType();
1856 SDLoc SL(Op);
1857
1858
1859 // If this is a 2 element vector, we really want to scalarize and not create
1860 // weird 1 element vectors.
1861 if (VT.getVectorNumElements() == 2) {
1862 SDValue Ops[2];
1863 std::tie(Ops[0], Ops[1]) = scalarizeVectorLoad(Load, DAG);
1864 return DAG.getMergeValues(Ops, SL);
1865 }
1866
1867 SDValue BasePtr = Load->getBasePtr();
1868 EVT MemVT = Load->getMemoryVT();
1869
1870 const MachinePointerInfo &SrcValue = Load->getMemOperand()->getPointerInfo();
1871
1872 EVT LoVT, HiVT;
1873 EVT LoMemVT, HiMemVT;
1874 SDValue Lo, Hi;
1875
1876 std::tie(LoVT, HiVT) = getSplitDestVTs(VT, DAG);
1877 std::tie(LoMemVT, HiMemVT) = getSplitDestVTs(MemVT, DAG);
1878 std::tie(Lo, Hi) = splitVector(Op, SL, LoVT, HiVT, DAG);
1879
1880 unsigned Size = LoMemVT.getStoreSize();
1881 Align BaseAlign = Load->getAlign();
1882 Align HiAlign = commonAlignment(BaseAlign, Size);
1883
1884 SDValue LoLoad = DAG.getExtLoad(
1885 Load->getExtensionType(), SL, LoVT, Load->getChain(), BasePtr, SrcValue,
1886 LoMemVT, BaseAlign, Load->getMemOperand()->getFlags(), Load->getAAInfo());
1887 SDValue HiPtr = DAG.getObjectPtrOffset(SL, BasePtr, TypeSize::getFixed(Size));
1888 SDValue HiLoad = DAG.getExtLoad(
1889 Load->getExtensionType(), SL, HiVT, Load->getChain(), HiPtr,
1890 SrcValue.getWithOffset(LoMemVT.getStoreSize()), HiMemVT, HiAlign,
1891 Load->getMemOperand()->getFlags(), Load->getAAInfo());
1892
1893 SDValue Join;
1894 if (LoVT == HiVT) {
1895 // This is the case that the vector is power of two so was evenly split.
1896 Join = DAG.getNode(ISD::CONCAT_VECTORS, SL, VT, LoLoad, HiLoad);
1897 } else {
1898 Join = DAG.getNode(ISD::INSERT_SUBVECTOR, SL, VT, DAG.getPOISON(VT), LoLoad,
1899 DAG.getVectorIdxConstant(0, SL));
1900 Join = DAG.getNode(
1902 VT, Join, HiLoad,
1904 }
1905
1906 SDValue Ops[] = {Join, DAG.getNode(ISD::TokenFactor, SL, MVT::Other,
1907 LoLoad.getValue(1), HiLoad.getValue(1))};
1908
1909 return DAG.getMergeValues(Ops, SL);
1910}
1911
1913 SelectionDAG &DAG) const {
1915 EVT VT = Op.getValueType();
1916 SDValue BasePtr = Load->getBasePtr();
1917 EVT MemVT = Load->getMemoryVT();
1918 SDLoc SL(Op);
1919 const MachinePointerInfo &SrcValue = Load->getMemOperand()->getPointerInfo();
1920 Align BaseAlign = Load->getAlign();
1921 unsigned NumElements = MemVT.getVectorNumElements();
1922
1923 // Widen from vec3 to vec4 when the load is at least 8-byte aligned
1924 // or 16-byte fully dereferenceable. Otherwise, split the vector load.
1925 if (NumElements != 3 ||
1926 (BaseAlign < Align(8) &&
1927 !SrcValue.isDereferenceable(16, *DAG.getContext(), DAG.getDataLayout())))
1928 return SplitVectorLoad(Op, DAG);
1929
1930 assert(NumElements == 3);
1931
1932 EVT WideVT =
1934 EVT WideMemVT =
1936 SDValue WideLoad = DAG.getExtLoad(
1937 Load->getExtensionType(), SL, WideVT, Load->getChain(), BasePtr, SrcValue,
1938 WideMemVT, BaseAlign, Load->getMemOperand()->getFlags());
1939 return DAG.getMergeValues(
1940 {DAG.getNode(ISD::EXTRACT_SUBVECTOR, SL, VT, WideLoad,
1941 DAG.getVectorIdxConstant(0, SL)),
1942 WideLoad.getValue(1)},
1943 SL);
1944}
1945
1947 SelectionDAG &DAG) const {
1949 SDValue Val = Store->getValue();
1950 EVT VT = Val.getValueType();
1951
1952 // If this is a 2 element vector, we really want to scalarize and not create
1953 // weird 1 element vectors.
1954 if (VT.getVectorNumElements() == 2)
1955 return scalarizeVectorStore(Store, DAG);
1956
1957 EVT MemVT = Store->getMemoryVT();
1958 SDValue Chain = Store->getChain();
1959 SDValue BasePtr = Store->getBasePtr();
1960 SDLoc SL(Op);
1961
1962 EVT LoVT, HiVT;
1963 EVT LoMemVT, HiMemVT;
1964 SDValue Lo, Hi;
1965
1966 std::tie(LoVT, HiVT) = getSplitDestVTs(VT, DAG);
1967 std::tie(LoMemVT, HiMemVT) = getSplitDestVTs(MemVT, DAG);
1968 std::tie(Lo, Hi) = splitVector(Val, SL, LoVT, HiVT, DAG);
1969
1970 SDValue HiPtr = DAG.getObjectPtrOffset(SL, BasePtr, LoMemVT.getStoreSize());
1971
1972 const MachinePointerInfo &SrcValue = Store->getMemOperand()->getPointerInfo();
1973 Align BaseAlign = Store->getAlign();
1974 unsigned Size = LoMemVT.getStoreSize();
1975 Align HiAlign = commonAlignment(BaseAlign, Size);
1976
1977 SDValue LoStore =
1978 DAG.getTruncStore(Chain, SL, Lo, BasePtr, SrcValue, LoMemVT, BaseAlign,
1979 Store->getMemOperand()->getFlags(), Store->getAAInfo());
1980 SDValue HiStore = DAG.getTruncStore(
1981 Chain, SL, Hi, HiPtr, SrcValue.getWithOffset(Size), HiMemVT, HiAlign,
1982 Store->getMemOperand()->getFlags(), Store->getAAInfo());
1983
1984 return DAG.getNode(ISD::TokenFactor, SL, MVT::Other, LoStore, HiStore);
1985}
1986
1987// This is a shortcut for integer division because we have fast i32<->f32
1988// conversions, and fast f32 reciprocal instructions.
1990 bool Sign) const {
1991 SDLoc DL(Op);
1992 EVT VT = Op.getValueType();
1993 assert(VT == MVT::i32 && "LowerDIVREMToFloat expects an i32");
1994
1995 SDValue LHS = Op.getOperand(0);
1996 SDValue RHS = Op.getOperand(1);
1997 MVT IntVT = MVT::i32;
1998 MVT FltVT = MVT::f32;
1999
2000 unsigned LHSSignBits;
2001 unsigned RHSSignBits;
2002 if (Sign) {
2003 LHSSignBits = DAG.ComputeNumSignBits(LHS);
2004 RHSSignBits = DAG.ComputeNumSignBits(RHS);
2005 if (LHSSignBits < 9 || RHSSignBits < 9)
2006 return SDValue();
2007 } else {
2008 KnownBits LHSKnown = DAG.computeKnownBits(LHS);
2009 KnownBits RHSKnown = DAG.computeKnownBits(RHS);
2010
2011 LHSSignBits = LHSKnown.countMinLeadingZeros();
2012 RHSSignBits = RHSKnown.countMinLeadingZeros();
2013 }
2014
2015 unsigned BitSize = VT.getSizeInBits();
2016 unsigned SignBits = std::min(LHSSignBits, RHSSignBits);
2017 unsigned DivBits = BitSize - SignBits;
2018 if (Sign)
2019 ++DivBits;
2020
2021 // In order to avoid problems due to 1 ulp accuracy issues with v_rcp_f32,
2022 // limit LowerDIVREMToFloat to:
2023 // [-0x400000,0x3FFFFF] for Sign
2024 // [ 0x000000,0x3FFFFF] for !Sign
2025 // This matches what is done in expandDivRemToFloatImpl.
2026 if (DivBits > (Sign ? 23 : 22))
2027 return SDValue();
2028
2031
2032 // int ia = (int)LHS;
2033 SDValue ia = LHS;
2034
2035 // int ib, (int)RHS;
2036 SDValue ib = RHS;
2037
2038 // The calculation:
2039 // fq = fa*recip(fb)
2040 // may be too small due to the 1ulp accuracy in the recip
2041 // operation and rounding issues. Since fq is truncated to produce
2042 // an integer value it may be too small by one. This is
2043 // dealt with by incrementing fa by 1ulp:
2044 // fq = (fa+1ulp)*recip(fb)
2045 // This will increase fa's magnitude by at most 0.5
2046 // (i.e. when fabs(fa)==0x400000 the LSB of the mantissa represents 0.5).
2047 // Thus, this method is safe since fa must be incremented by at least 1.0
2048 // for the quotient to increase by one.
2049 SDValue fa = DAG.getNode(ToFp, DL, FltVT, ia);
2050 SDValue faAsInt = DAG.getNode(ISD::BITCAST, DL, MVT::i32, fa);
2051 SDValue faIncremented = DAG.getNode(ISD::ADD, DL, MVT::i32, faAsInt,
2052 DAG.getConstant(1, DL, MVT::i32));
2053 fa = DAG.getNode(ISD::BITCAST, DL, FltVT, faIncremented);
2054
2055 // float fb = (float)ib;
2056 SDValue fb = DAG.getNode(ToFp, DL, FltVT, ib);
2057
2058 SDValue fq = DAG.getNode(ISD::FMUL, DL, FltVT,
2059 fa, DAG.getNode(AMDGPUISD::RCP, DL, FltVT, fb));
2060
2061 // fq = trunc(fq);
2062 fq = DAG.getNode(ISD::FTRUNC, DL, FltVT, fq);
2063
2064 // int iq = (int)fq;
2065 SDValue Div = DAG.getNode(ToInt, DL, IntVT, fq);
2066
2067 // Rem needs compensation, it's easier to recompute it
2068 SDValue Rem = DAG.getNode(ISD::MUL, DL, VT, Div, RHS);
2069 Rem = DAG.getNode(ISD::SUB, DL, VT, LHS, Rem);
2070
2071 return DAG.getMergeValues({ Div, Rem }, DL);
2072}
2073
2075 SelectionDAG &DAG,
2077 SDLoc DL(Op);
2078 EVT VT = Op.getValueType();
2079
2080 assert(VT == MVT::i64 && "LowerUDIVREM64 expects an i64");
2081
2082 EVT HalfVT = VT.getHalfSizedIntegerVT(*DAG.getContext());
2083
2084 SDValue One = DAG.getConstant(1, DL, HalfVT);
2085 SDValue Zero = DAG.getConstant(0, DL, HalfVT);
2086
2087 //HiLo split
2088 SDValue LHS_Lo, LHS_Hi;
2089 SDValue LHS = Op.getOperand(0);
2090 std::tie(LHS_Lo, LHS_Hi) = DAG.SplitScalar(LHS, DL, HalfVT, HalfVT);
2091
2092 SDValue RHS_Lo, RHS_Hi;
2093 SDValue RHS = Op.getOperand(1);
2094 std::tie(RHS_Lo, RHS_Hi) = DAG.SplitScalar(RHS, DL, HalfVT, HalfVT);
2095
2096 if (DAG.MaskedValueIsZero(RHS, APInt::getHighBitsSet(64, 32)) &&
2097 DAG.MaskedValueIsZero(LHS, APInt::getHighBitsSet(64, 32))) {
2098
2099 SDValue Res = DAG.getNode(ISD::UDIVREM, DL, DAG.getVTList(HalfVT, HalfVT),
2100 LHS_Lo, RHS_Lo);
2101
2102 SDValue DIV = DAG.getBuildVector(MVT::v2i32, DL, {Res.getValue(0), Zero});
2103 SDValue REM = DAG.getBuildVector(MVT::v2i32, DL, {Res.getValue(1), Zero});
2104
2105 Results.push_back(DAG.getNode(ISD::BITCAST, DL, MVT::i64, DIV));
2106 Results.push_back(DAG.getNode(ISD::BITCAST, DL, MVT::i64, REM));
2107 return;
2108 }
2109
2110 if (isTypeLegal(MVT::i64)) {
2111 // The algorithm here is based on ideas from "Software Integer Division",
2112 // Tom Rodeheffer, August 2008.
2113
2116
2117 // Compute denominator reciprocal.
2118 unsigned FMAD =
2119 !Subtarget->hasMadMacF32Insts() ? (unsigned)ISD::FMA
2122 : (unsigned)AMDGPUISD::FMAD_FTZ;
2123
2124 SDValue Cvt_Lo = DAG.getNode(ISD::UINT_TO_FP, DL, MVT::f32, RHS_Lo);
2125 SDValue Cvt_Hi = DAG.getNode(ISD::UINT_TO_FP, DL, MVT::f32, RHS_Hi);
2126 SDValue Mad1 = DAG.getNode(FMAD, DL, MVT::f32, Cvt_Hi,
2127 DAG.getConstantFP(APInt(32, 0x4f800000).bitsToFloat(), DL, MVT::f32),
2128 Cvt_Lo);
2129 SDValue Rcp = DAG.getNode(AMDGPUISD::RCP, DL, MVT::f32, Mad1);
2130 SDValue Mul1 = DAG.getNode(ISD::FMUL, DL, MVT::f32, Rcp,
2131 DAG.getConstantFP(APInt(32, 0x5f7ffffc).bitsToFloat(), DL, MVT::f32));
2132 SDValue Mul2 = DAG.getNode(ISD::FMUL, DL, MVT::f32, Mul1,
2133 DAG.getConstantFP(APInt(32, 0x2f800000).bitsToFloat(), DL, MVT::f32));
2134 SDValue Trunc = DAG.getNode(ISD::FTRUNC, DL, MVT::f32, Mul2);
2135 SDValue Mad2 = DAG.getNode(FMAD, DL, MVT::f32, Trunc,
2136 DAG.getConstantFP(APInt(32, 0xcf800000).bitsToFloat(), DL, MVT::f32),
2137 Mul1);
2138 SDValue Rcp_Lo = DAG.getNode(ISD::FP_TO_UINT, DL, HalfVT, Mad2);
2139 SDValue Rcp_Hi = DAG.getNode(ISD::FP_TO_UINT, DL, HalfVT, Trunc);
2140 SDValue Rcp64 = DAG.getBitcast(VT,
2141 DAG.getBuildVector(MVT::v2i32, DL, {Rcp_Lo, Rcp_Hi}));
2142
2143 SDValue Zero64 = DAG.getConstant(0, DL, VT);
2144 SDValue One64 = DAG.getConstant(1, DL, VT);
2145 SDValue Zero1 = DAG.getConstant(0, DL, MVT::i1);
2146 SDVTList HalfCarryVT = DAG.getVTList(HalfVT, MVT::i1);
2147
2148 // First round of UNR (Unsigned integer Newton-Raphson).
2149 SDValue Neg_RHS = DAG.getNode(ISD::SUB, DL, VT, Zero64, RHS);
2150 SDValue Mullo1 = DAG.getNode(ISD::MUL, DL, VT, Neg_RHS, Rcp64);
2151 SDValue Mulhi1 = DAG.getNode(ISD::MULHU, DL, VT, Rcp64, Mullo1);
2152 SDValue Mulhi1_Lo, Mulhi1_Hi;
2153 std::tie(Mulhi1_Lo, Mulhi1_Hi) =
2154 DAG.SplitScalar(Mulhi1, DL, HalfVT, HalfVT);
2155 SDValue Add1_Lo = DAG.getNode(ISD::UADDO_CARRY, DL, HalfCarryVT, Rcp_Lo,
2156 Mulhi1_Lo, Zero1);
2157 SDValue Add1_Hi = DAG.getNode(ISD::UADDO_CARRY, DL, HalfCarryVT, Rcp_Hi,
2158 Mulhi1_Hi, Add1_Lo.getValue(1));
2159 SDValue Add1 = DAG.getBitcast(VT,
2160 DAG.getBuildVector(MVT::v2i32, DL, {Add1_Lo, Add1_Hi}));
2161
2162 // Second round of UNR.
2163 SDValue Mullo2 = DAG.getNode(ISD::MUL, DL, VT, Neg_RHS, Add1);
2164 SDValue Mulhi2 = DAG.getNode(ISD::MULHU, DL, VT, Add1, Mullo2);
2165 SDValue Mulhi2_Lo, Mulhi2_Hi;
2166 std::tie(Mulhi2_Lo, Mulhi2_Hi) =
2167 DAG.SplitScalar(Mulhi2, DL, HalfVT, HalfVT);
2168 SDValue Add2_Lo = DAG.getNode(ISD::UADDO_CARRY, DL, HalfCarryVT, Add1_Lo,
2169 Mulhi2_Lo, Zero1);
2170 SDValue Add2_Hi = DAG.getNode(ISD::UADDO_CARRY, DL, HalfCarryVT, Add1_Hi,
2171 Mulhi2_Hi, Add2_Lo.getValue(1));
2172 SDValue Add2 = DAG.getBitcast(VT,
2173 DAG.getBuildVector(MVT::v2i32, DL, {Add2_Lo, Add2_Hi}));
2174
2175 SDValue Mulhi3 = DAG.getNode(ISD::MULHU, DL, VT, LHS, Add2);
2176
2177 SDValue Mul3 = DAG.getNode(ISD::MUL, DL, VT, RHS, Mulhi3);
2178
2179 SDValue Mul3_Lo, Mul3_Hi;
2180 std::tie(Mul3_Lo, Mul3_Hi) = DAG.SplitScalar(Mul3, DL, HalfVT, HalfVT);
2181 SDValue Sub1_Lo = DAG.getNode(ISD::USUBO_CARRY, DL, HalfCarryVT, LHS_Lo,
2182 Mul3_Lo, Zero1);
2183 SDValue Sub1_Hi = DAG.getNode(ISD::USUBO_CARRY, DL, HalfCarryVT, LHS_Hi,
2184 Mul3_Hi, Sub1_Lo.getValue(1));
2185 SDValue Sub1_Mi = DAG.getNode(ISD::SUB, DL, HalfVT, LHS_Hi, Mul3_Hi);
2186 SDValue Sub1 = DAG.getBitcast(VT,
2187 DAG.getBuildVector(MVT::v2i32, DL, {Sub1_Lo, Sub1_Hi}));
2188
2189 SDValue MinusOne = DAG.getConstant(0xffffffffu, DL, HalfVT);
2190 SDValue C1 = DAG.getSelectCC(DL, Sub1_Hi, RHS_Hi, MinusOne, Zero,
2191 ISD::SETUGE);
2192 SDValue C2 = DAG.getSelectCC(DL, Sub1_Lo, RHS_Lo, MinusOne, Zero,
2193 ISD::SETUGE);
2194 SDValue C3 = DAG.getSelectCC(DL, Sub1_Hi, RHS_Hi, C2, C1, ISD::SETEQ);
2195
2196 // TODO: Here and below portions of the code can be enclosed into if/endif.
2197 // Currently control flow is unconditional and we have 4 selects after
2198 // potential endif to substitute PHIs.
2199
2200 // if C3 != 0 ...
2201 SDValue Sub2_Lo = DAG.getNode(ISD::USUBO_CARRY, DL, HalfCarryVT, Sub1_Lo,
2202 RHS_Lo, Zero1);
2203 SDValue Sub2_Mi = DAG.getNode(ISD::USUBO_CARRY, DL, HalfCarryVT, Sub1_Mi,
2204 RHS_Hi, Sub1_Lo.getValue(1));
2205 SDValue Sub2_Hi = DAG.getNode(ISD::USUBO_CARRY, DL, HalfCarryVT, Sub2_Mi,
2206 Zero, Sub2_Lo.getValue(1));
2207 SDValue Sub2 = DAG.getBitcast(VT,
2208 DAG.getBuildVector(MVT::v2i32, DL, {Sub2_Lo, Sub2_Hi}));
2209
2210 SDValue Add3 = DAG.getNode(ISD::ADD, DL, VT, Mulhi3, One64);
2211
2212 SDValue C4 = DAG.getSelectCC(DL, Sub2_Hi, RHS_Hi, MinusOne, Zero,
2213 ISD::SETUGE);
2214 SDValue C5 = DAG.getSelectCC(DL, Sub2_Lo, RHS_Lo, MinusOne, Zero,
2215 ISD::SETUGE);
2216 SDValue C6 = DAG.getSelectCC(DL, Sub2_Hi, RHS_Hi, C5, C4, ISD::SETEQ);
2217
2218 // if (C6 != 0)
2219 SDValue Add4 = DAG.getNode(ISD::ADD, DL, VT, Add3, One64);
2220
2221 SDValue Sub3_Lo = DAG.getNode(ISD::USUBO_CARRY, DL, HalfCarryVT, Sub2_Lo,
2222 RHS_Lo, Zero1);
2223 SDValue Sub3_Mi = DAG.getNode(ISD::USUBO_CARRY, DL, HalfCarryVT, Sub2_Mi,
2224 RHS_Hi, Sub2_Lo.getValue(1));
2225 SDValue Sub3_Hi = DAG.getNode(ISD::USUBO_CARRY, DL, HalfCarryVT, Sub3_Mi,
2226 Zero, Sub3_Lo.getValue(1));
2227 SDValue Sub3 = DAG.getBitcast(VT,
2228 DAG.getBuildVector(MVT::v2i32, DL, {Sub3_Lo, Sub3_Hi}));
2229
2230 // endif C6
2231 // endif C3
2232
2233 SDValue Sel1 = DAG.getSelectCC(DL, C6, Zero, Add4, Add3, ISD::SETNE);
2234 SDValue Div = DAG.getSelectCC(DL, C3, Zero, Sel1, Mulhi3, ISD::SETNE);
2235
2236 SDValue Sel2 = DAG.getSelectCC(DL, C6, Zero, Sub3, Sub2, ISD::SETNE);
2237 SDValue Rem = DAG.getSelectCC(DL, C3, Zero, Sel2, Sub1, ISD::SETNE);
2238
2239 Results.push_back(Div);
2240 Results.push_back(Rem);
2241
2242 return;
2243 }
2244
2245 // r600 expandion.
2246 // Get Speculative values
2247 SDValue DIV_Part = DAG.getNode(ISD::UDIV, DL, HalfVT, LHS_Hi, RHS_Lo);
2248 SDValue REM_Part = DAG.getNode(ISD::UREM, DL, HalfVT, LHS_Hi, RHS_Lo);
2249
2250 SDValue REM_Lo = DAG.getSelectCC(DL, RHS_Hi, Zero, REM_Part, LHS_Hi, ISD::SETEQ);
2251 SDValue REM = DAG.getBuildVector(MVT::v2i32, DL, {REM_Lo, Zero});
2252 REM = DAG.getNode(ISD::BITCAST, DL, MVT::i64, REM);
2253
2254 SDValue DIV_Hi = DAG.getSelectCC(DL, RHS_Hi, Zero, DIV_Part, Zero, ISD::SETEQ);
2255 SDValue DIV_Lo = Zero;
2256
2257 const unsigned halfBitWidth = HalfVT.getSizeInBits();
2258
2259 for (unsigned i = 0; i < halfBitWidth; ++i) {
2260 const unsigned bitPos = halfBitWidth - i - 1;
2261 SDValue POS = DAG.getConstant(bitPos, DL, HalfVT);
2262 // Get value of high bit
2263 SDValue HBit = DAG.getNode(ISD::SRL, DL, HalfVT, LHS_Lo, POS);
2264 HBit = DAG.getNode(ISD::AND, DL, HalfVT, HBit, One);
2265 HBit = DAG.getNode(ISD::ZERO_EXTEND, DL, VT, HBit);
2266
2267 // Shift
2268 REM = DAG.getNode(ISD::SHL, DL, VT, REM, DAG.getConstant(1, DL, VT));
2269 // Add LHS high bit
2270 REM = DAG.getNode(ISD::OR, DL, VT, REM, HBit);
2271
2272 SDValue BIT = DAG.getConstant(1ULL << bitPos, DL, HalfVT);
2273 SDValue realBIT = DAG.getSelectCC(DL, REM, RHS, BIT, Zero, ISD::SETUGE);
2274
2275 DIV_Lo = DAG.getNode(ISD::OR, DL, HalfVT, DIV_Lo, realBIT);
2276
2277 // Update REM
2278 SDValue REM_sub = DAG.getNode(ISD::SUB, DL, VT, REM, RHS);
2279 REM = DAG.getSelectCC(DL, REM, RHS, REM_sub, REM, ISD::SETUGE);
2280 }
2281
2282 SDValue DIV = DAG.getBuildVector(MVT::v2i32, DL, {DIV_Lo, DIV_Hi});
2283 DIV = DAG.getNode(ISD::BITCAST, DL, MVT::i64, DIV);
2284 Results.push_back(DIV);
2285 Results.push_back(REM);
2286}
2287
2289 SelectionDAG &DAG) const {
2290 SDLoc DL(Op);
2291 EVT VT = Op.getValueType();
2292
2293 if (VT == MVT::i64) {
2295 LowerUDIVREM64(Op, DAG, Results);
2296 return DAG.getMergeValues(Results, DL);
2297 }
2298
2299 if (VT == MVT::i32) {
2300 if (SDValue Res = LowerDIVREMToFloat(Op, DAG, false))
2301 return Res;
2302 }
2303
2304 SDValue X = Op.getOperand(0);
2305 SDValue Y = Op.getOperand(1);
2306
2307 // See AMDGPUCodeGenPrepare::expandDivRem32 for a description of the
2308 // algorithm used here.
2309
2310 // Initial estimate of inv(y).
2311 SDValue Z = DAG.getNode(AMDGPUISD::URECIP, DL, VT, Y);
2312
2313 // One round of UNR.
2314 SDValue NegY = DAG.getNode(ISD::SUB, DL, VT, DAG.getConstant(0, DL, VT), Y);
2315 SDValue NegYZ = DAG.getNode(ISD::MUL, DL, VT, NegY, Z);
2316 Z = DAG.getNode(ISD::ADD, DL, VT, Z,
2317 DAG.getNode(ISD::MULHU, DL, VT, Z, NegYZ));
2318
2319 // Quotient/remainder estimate.
2320 SDValue Q = DAG.getNode(ISD::MULHU, DL, VT, X, Z);
2321 SDValue R =
2322 DAG.getNode(ISD::SUB, DL, VT, X, DAG.getNode(ISD::MUL, DL, VT, Q, Y));
2323
2324 // First quotient/remainder refinement.
2325 EVT CCVT = getSetCCResultType(DAG.getDataLayout(), *DAG.getContext(), VT);
2326 SDValue One = DAG.getConstant(1, DL, VT);
2327 SDValue Cond = DAG.getSetCC(DL, CCVT, R, Y, ISD::SETUGE);
2328 Q = DAG.getNode(ISD::SELECT, DL, VT, Cond,
2329 DAG.getNode(ISD::ADD, DL, VT, Q, One), Q);
2330 R = DAG.getNode(ISD::SELECT, DL, VT, Cond,
2331 DAG.getNode(ISD::SUB, DL, VT, R, Y), R);
2332
2333 // Second quotient/remainder refinement.
2334 Cond = DAG.getSetCC(DL, CCVT, R, Y, ISD::SETUGE);
2335 Q = DAG.getNode(ISD::SELECT, DL, VT, Cond,
2336 DAG.getNode(ISD::ADD, DL, VT, Q, One), Q);
2337 R = DAG.getNode(ISD::SELECT, DL, VT, Cond,
2338 DAG.getNode(ISD::SUB, DL, VT, R, Y), R);
2339
2340 return DAG.getMergeValues({Q, R}, DL);
2341}
2342
2344 SelectionDAG &DAG) const {
2345 SDLoc DL(Op);
2346 EVT VT = Op.getValueType();
2347
2348 SDValue LHS = Op.getOperand(0);
2349 SDValue RHS = Op.getOperand(1);
2350
2351 SDValue Zero = DAG.getConstant(0, DL, VT);
2352 SDValue NegOne = DAG.getAllOnesConstant(DL, VT);
2353
2354 if (VT == MVT::i32) {
2355 if (SDValue Res = LowerDIVREMToFloat(Op, DAG, true))
2356 return Res;
2357 }
2358
2359 // LHS must have > 33 sign-bits to ensure that LHS != -2147483648
2360 // Otherwise 32-bit division cannot be used safely.
2361 // -2147483648/1 and -2147483648/-1 are not equal,
2362 // but they produce the same lower 32-bit result.
2363 if (VT == MVT::i64 && DAG.ComputeNumSignBits(LHS) > 33 &&
2364 DAG.ComputeNumSignBits(RHS) > 32) {
2365 EVT HalfVT = VT.getHalfSizedIntegerVT(*DAG.getContext());
2366
2367 //HiLo split
2368 SDValue LHS_Lo = DAG.getNode(ISD::EXTRACT_ELEMENT, DL, HalfVT, LHS, Zero);
2369 SDValue RHS_Lo = DAG.getNode(ISD::EXTRACT_ELEMENT, DL, HalfVT, RHS, Zero);
2370 SDValue DIVREM = DAG.getNode(ISD::SDIVREM, DL, DAG.getVTList(HalfVT, HalfVT),
2371 LHS_Lo, RHS_Lo);
2372 SDValue Res[2] = {
2373 DAG.getNode(ISD::SIGN_EXTEND, DL, VT, DIVREM.getValue(0)),
2374 DAG.getNode(ISD::SIGN_EXTEND, DL, VT, DIVREM.getValue(1))
2375 };
2376 return DAG.getMergeValues(Res, DL);
2377 }
2378
2379 SDValue LHSign = DAG.getSelectCC(DL, LHS, Zero, NegOne, Zero, ISD::SETLT);
2380 SDValue RHSign = DAG.getSelectCC(DL, RHS, Zero, NegOne, Zero, ISD::SETLT);
2381 SDValue DSign = DAG.getNode(ISD::XOR, DL, VT, LHSign, RHSign);
2382 SDValue RSign = LHSign; // Remainder sign is the same as LHS
2383
2384 LHS = DAG.getNode(ISD::ADD, DL, VT, LHS, LHSign);
2385 RHS = DAG.getNode(ISD::ADD, DL, VT, RHS, RHSign);
2386
2387 LHS = DAG.getNode(ISD::XOR, DL, VT, LHS, LHSign);
2388 RHS = DAG.getNode(ISD::XOR, DL, VT, RHS, RHSign);
2389
2390 SDValue Div = DAG.getNode(ISD::UDIVREM, DL, DAG.getVTList(VT, VT), LHS, RHS);
2391 SDValue Rem = Div.getValue(1);
2392
2393 Div = DAG.getNode(ISD::XOR, DL, VT, Div, DSign);
2394 Rem = DAG.getNode(ISD::XOR, DL, VT, Rem, RSign);
2395
2396 Div = DAG.getNode(ISD::SUB, DL, VT, Div, DSign);
2397 Rem = DAG.getNode(ISD::SUB, DL, VT, Rem, RSign);
2398
2399 SDValue Res[2] = {
2400 Div,
2401 Rem
2402 };
2403 return DAG.getMergeValues(Res, DL);
2404}
2405
2407 SDLoc SL(Op);
2408 SDValue Src = Op.getOperand(0);
2409
2410 // result = trunc(src)
2411 // if (src > 0.0 && src != result)
2412 // result += 1.0
2413
2414 SDValue Trunc = DAG.getNode(ISD::FTRUNC, SL, MVT::f64, Src);
2415
2416 const SDValue Zero = DAG.getConstantFP(0.0, SL, MVT::f64);
2417 const SDValue One = DAG.getConstantFP(1.0, SL, MVT::f64);
2418
2419 EVT SetCCVT =
2420 getSetCCResultType(DAG.getDataLayout(), *DAG.getContext(), MVT::f64);
2421
2422 SDValue Lt0 = DAG.getSetCC(SL, SetCCVT, Src, Zero, ISD::SETOGT);
2423 SDValue NeTrunc = DAG.getSetCC(SL, SetCCVT, Src, Trunc, ISD::SETONE);
2424 SDValue And = DAG.getNode(ISD::AND, SL, SetCCVT, Lt0, NeTrunc);
2425
2426 SDValue Add = DAG.getNode(ISD::SELECT, SL, MVT::f64, And, One, Zero);
2427 // TODO: Should this propagate fast-math-flags?
2428 return DAG.getNode(ISD::FADD, SL, MVT::f64, Trunc, Add);
2429}
2430
2432 SelectionDAG &DAG) {
2433 const unsigned FractBits = 52;
2434 const unsigned ExpBits = 11;
2435
2436 SDValue ExpPart = DAG.getNode(AMDGPUISD::BFE_U32, SL, MVT::i32,
2437 Hi,
2438 DAG.getConstant(FractBits - 32, SL, MVT::i32),
2439 DAG.getConstant(ExpBits, SL, MVT::i32));
2440 SDValue Exp = DAG.getNode(ISD::SUB, SL, MVT::i32, ExpPart,
2441 DAG.getConstant(1023, SL, MVT::i32));
2442
2443 return Exp;
2444}
2445
2447 SDLoc SL(Op);
2448 SDValue Src = Op.getOperand(0);
2449
2450 assert(Op.getValueType() == MVT::f64);
2451
2452 const SDValue Zero = DAG.getConstant(0, SL, MVT::i32);
2453
2454 // Extract the upper half, since this is where we will find the sign and
2455 // exponent.
2456 SDValue Hi = getHiHalf64(Src, DAG);
2457
2458 SDValue Exp = extractF64Exponent(Hi, SL, DAG);
2459
2460 const unsigned FractBits = 52;
2461
2462 // Extract the sign bit.
2463 const SDValue SignBitMask = DAG.getConstant(UINT32_C(1) << 31, SL, MVT::i32);
2464 SDValue SignBit = DAG.getNode(ISD::AND, SL, MVT::i32, Hi, SignBitMask);
2465
2466 // Extend back to 64-bits.
2467 SDValue SignBit64 = DAG.getBuildVector(MVT::v2i32, SL, {Zero, SignBit});
2468 SignBit64 = DAG.getNode(ISD::BITCAST, SL, MVT::i64, SignBit64);
2469
2470 SDValue BcInt = DAG.getNode(ISD::BITCAST, SL, MVT::i64, Src);
2471 const SDValue FractMask
2472 = DAG.getConstant((UINT64_C(1) << FractBits) - 1, SL, MVT::i64);
2473
2474 SDValue Shr = DAG.getNode(ISD::SRA, SL, MVT::i64, FractMask, Exp);
2475 SDValue Not = DAG.getNOT(SL, Shr, MVT::i64);
2476 SDValue Tmp0 = DAG.getNode(ISD::AND, SL, MVT::i64, BcInt, Not);
2477
2478 EVT SetCCVT =
2479 getSetCCResultType(DAG.getDataLayout(), *DAG.getContext(), MVT::i32);
2480
2481 const SDValue FiftyOne = DAG.getConstant(FractBits - 1, SL, MVT::i32);
2482
2483 SDValue ExpLt0 = DAG.getSetCC(SL, SetCCVT, Exp, Zero, ISD::SETLT);
2484 SDValue ExpGt51 = DAG.getSetCC(SL, SetCCVT, Exp, FiftyOne, ISD::SETGT);
2485
2486 SDValue Tmp1 = DAG.getNode(ISD::SELECT, SL, MVT::i64, ExpLt0, SignBit64, Tmp0);
2487 SDValue Tmp2 = DAG.getNode(ISD::SELECT, SL, MVT::i64, ExpGt51, BcInt, Tmp1);
2488
2489 return DAG.getNode(ISD::BITCAST, SL, MVT::f64, Tmp2);
2490}
2491
2493 SelectionDAG &DAG) const {
2494 SDLoc SL(Op);
2495 SDValue Src = Op.getOperand(0);
2496
2497 assert(Op.getValueType() == MVT::f64);
2498
2499 APFloat C1Val(APFloat::IEEEdouble(), "0x1.0p+52");
2500 SDValue C1 = DAG.getConstantFP(C1Val, SL, MVT::f64);
2501 SDValue CopySign = DAG.getNode(ISD::FCOPYSIGN, SL, MVT::f64, C1, Src);
2502
2503 // TODO: Should this propagate fast-math-flags?
2504
2505 SDValue Tmp1 = DAG.getNode(ISD::FADD, SL, MVT::f64, Src, CopySign);
2506 SDValue Tmp2 = DAG.getNode(ISD::FSUB, SL, MVT::f64, Tmp1, CopySign);
2507
2508 SDValue Fabs = DAG.getNode(ISD::FABS, SL, MVT::f64, Src);
2509
2510 APFloat C2Val(APFloat::IEEEdouble(), "0x1.fffffffffffffp+51");
2511 SDValue C2 = DAG.getConstantFP(C2Val, SL, MVT::f64);
2512
2513 EVT SetCCVT =
2514 getSetCCResultType(DAG.getDataLayout(), *DAG.getContext(), MVT::f64);
2515 SDValue Cond = DAG.getSetCC(SL, SetCCVT, Fabs, C2, ISD::SETOGT);
2516
2517 return DAG.getSelect(SL, MVT::f64, Cond, Src, Tmp2);
2518}
2519
2521 SelectionDAG &DAG) const {
2522 // FNEARBYINT and FRINT are the same, except in their handling of FP
2523 // exceptions. Those aren't really meaningful for us, and OpenCL only has
2524 // rint, so just treat them as equivalent.
2525 return DAG.getNode(ISD::FROUNDEVEN, SDLoc(Op), Op.getValueType(),
2526 Op.getOperand(0));
2527}
2528
2530 auto VT = Op.getValueType();
2531 auto Arg = Op.getOperand(0u);
2532 return DAG.getNode(ISD::FROUNDEVEN, SDLoc(Op), VT, Arg);
2533}
2534
2535// XXX - May require not supporting f32 denormals?
2536
2537// Don't handle v2f16. The extra instructions to scalarize and repack around the
2538// compare and vselect end up producing worse code than scalarizing the whole
2539// operation.
2541 SDLoc SL(Op);
2542 SDValue X = Op.getOperand(0);
2543 EVT VT = Op.getValueType();
2544
2545 SDValue T = DAG.getNode(ISD::FTRUNC, SL, VT, X);
2546
2547 // TODO: Should this propagate fast-math-flags?
2548
2549 SDValue Diff = DAG.getNode(ISD::FSUB, SL, VT, X, T);
2550
2551 SDValue AbsDiff = DAG.getNode(ISD::FABS, SL, VT, Diff);
2552
2553 const SDValue Zero = DAG.getConstantFP(0.0, SL, VT);
2554 const SDValue One = DAG.getConstantFP(1.0, SL, VT);
2555
2556 EVT SetCCVT =
2557 getSetCCResultType(DAG.getDataLayout(), *DAG.getContext(), VT);
2558
2559 const SDValue Half = DAG.getConstantFP(0.5, SL, VT);
2560 SDValue Cmp = DAG.getSetCC(SL, SetCCVT, AbsDiff, Half, ISD::SETOGE);
2561 SDValue OneOrZeroFP = DAG.getNode(ISD::SELECT, SL, VT, Cmp, One, Zero);
2562
2563 SDValue SignedOffset = DAG.getNode(ISD::FCOPYSIGN, SL, VT, OneOrZeroFP, X);
2564 return DAG.getNode(ISD::FADD, SL, VT, T, SignedOffset);
2565}
2566
2568 SDLoc SL(Op);
2569 SDValue Src = Op.getOperand(0);
2570
2571 // result = trunc(src);
2572 // if (src < 0.0 && src != result)
2573 // result += -1.0.
2574
2575 SDValue Trunc = DAG.getNode(ISD::FTRUNC, SL, MVT::f64, Src);
2576
2577 const SDValue Zero = DAG.getConstantFP(0.0, SL, MVT::f64);
2578 const SDValue NegOne = DAG.getConstantFP(-1.0, SL, MVT::f64);
2579
2580 EVT SetCCVT =
2581 getSetCCResultType(DAG.getDataLayout(), *DAG.getContext(), MVT::f64);
2582
2583 SDValue Lt0 = DAG.getSetCC(SL, SetCCVT, Src, Zero, ISD::SETOLT);
2584 SDValue NeTrunc = DAG.getSetCC(SL, SetCCVT, Src, Trunc, ISD::SETONE);
2585 SDValue And = DAG.getNode(ISD::AND, SL, SetCCVT, Lt0, NeTrunc);
2586
2587 SDValue Add = DAG.getNode(ISD::SELECT, SL, MVT::f64, And, NegOne, Zero);
2588 // TODO: Should this propagate fast-math-flags?
2589 return DAG.getNode(ISD::FADD, SL, MVT::f64, Trunc, Add);
2590}
2591
2592/// Return true if it's known that \p Src can never be an f32 denormal value.
2594 switch (Src.getOpcode()) {
2595 case ISD::FP_EXTEND:
2596 return Src.getOperand(0).getValueType() == MVT::f16;
2597 case ISD::FP16_TO_FP:
2598 case ISD::FFREXP:
2599 case ISD::FSQRT:
2600 case AMDGPUISD::LOG:
2601 case AMDGPUISD::EXP:
2602 return true;
2604 unsigned IntrinsicID = Src.getConstantOperandVal(0);
2605 switch (IntrinsicID) {
2606 case Intrinsic::amdgcn_frexp_mant:
2607 case Intrinsic::amdgcn_log:
2608 case Intrinsic::amdgcn_log_clamp:
2609 case Intrinsic::amdgcn_exp2:
2610 case Intrinsic::amdgcn_sqrt:
2611 return true;
2612 default:
2613 return false;
2614 }
2615 }
2616 default:
2617 return false;
2618 }
2619
2620 llvm_unreachable("covered opcode switch");
2621}
2622
2624 SDNodeFlags Flags) {
2625 return Flags.hasApproximateFuncs();
2626}
2627
2636
2638 SDNodeFlags Flags) const {
2639 SDLoc SL(Src);
2640 EVT VT = Src.getValueType();
2641 const fltSemantics &Semantics = VT.getFltSemantics();
2642 SDValue Inf = DAG.getConstantFP(APFloat::getInf(Semantics), SL, VT);
2643
2644 SDValue Fabs = DAG.getNode(ISD::FABS, SL, VT, Src, Flags);
2645 SDValue IsFinite = DAG.getSetCC(
2646 SL, getSetCCResultType(DAG.getDataLayout(), *DAG.getContext(), VT), Fabs,
2647 Inf, ISD::SETOLT);
2648 return IsFinite;
2649}
2650
2651/// If denormal handling is required return the scaled input to FLOG2, and the
2652/// check for denormal range. Otherwise, return null values.
2653std::pair<SDValue, SDValue>
2655 SDValue Src, SDNodeFlags Flags) const {
2656 if (!needsDenormHandlingF32(DAG, Src, Flags))
2657 return {};
2658
2659 MVT VT = MVT::f32;
2660 const fltSemantics &Semantics = APFloat::IEEEsingle();
2661 SDValue SmallestNormal =
2662 DAG.getConstantFP(APFloat::getSmallestNormalized(Semantics), SL, VT);
2663
2664 SDValue IsLtSmallestNormal = DAG.getSetCC(
2665 SL, getSetCCResultType(DAG.getDataLayout(), *DAG.getContext(), VT), Src,
2666 SmallestNormal, ISD::SETOLT);
2667
2668 SDValue Scale32 = DAG.getConstantFP(0x1.0p+32, SL, VT);
2669 SDValue One = DAG.getConstantFP(1.0, SL, VT);
2670 SDValue ScaleFactor =
2671 DAG.getNode(ISD::SELECT, SL, VT, IsLtSmallestNormal, Scale32, One, Flags);
2672
2673 SDValue ScaledInput = DAG.getNode(ISD::FMUL, SL, VT, Src, ScaleFactor, Flags);
2674 return {ScaledInput, IsLtSmallestNormal};
2675}
2676
2678 // v_log_f32 is good enough for OpenCL, except it doesn't handle denormals.
2679 // If we have to handle denormals, scale up the input and adjust the result.
2680
2681 // scaled = x * (is_denormal ? 0x1.0p+32 : 1.0)
2682 // log2 = amdgpu_log2 - (is_denormal ? 32.0 : 0.0)
2683
2684 SDLoc SL(Op);
2685 EVT VT = Op.getValueType();
2686 SDValue Src = Op.getOperand(0);
2687 SDNodeFlags Flags = Op->getFlags();
2688
2689 if (VT == MVT::f16) {
2690 // Nothing in half is a denormal when promoted to f32.
2691 assert(!isTypeLegal(VT));
2692 SDValue Ext = DAG.getNode(ISD::FP_EXTEND, SL, MVT::f32, Src, Flags);
2693 SDValue Log = DAG.getNode(AMDGPUISD::LOG, SL, MVT::f32, Ext, Flags);
2694 return DAG.getNode(ISD::FP_ROUND, SL, VT, Log,
2695 DAG.getTargetConstant(0, SL, MVT::i32), Flags);
2696 }
2697
2698 auto [ScaledInput, IsLtSmallestNormal] =
2699 getScaledLogInput(DAG, SL, Src, Flags);
2700 if (!ScaledInput)
2701 return DAG.getNode(AMDGPUISD::LOG, SL, VT, Src, Flags);
2702
2703 SDValue Log2 = DAG.getNode(AMDGPUISD::LOG, SL, VT, ScaledInput, Flags);
2704
2705 SDValue ThirtyTwo = DAG.getConstantFP(32.0, SL, VT);
2706 SDValue Zero = DAG.getConstantFP(0.0, SL, VT);
2707 SDValue ResultOffset =
2708 DAG.getNode(ISD::SELECT, SL, VT, IsLtSmallestNormal, ThirtyTwo, Zero);
2709 return DAG.getNode(ISD::FSUB, SL, VT, Log2, ResultOffset, Flags);
2710}
2711
2712static SDValue getMad(SelectionDAG &DAG, const SDLoc &SL, EVT VT, SDValue X,
2713 SDValue Y, SDValue C, SDNodeFlags Flags = SDNodeFlags()) {
2714 SDValue Mul = DAG.getNode(ISD::FMUL, SL, VT, X, Y, Flags);
2715 return DAG.getNode(ISD::FADD, SL, VT, Mul, C, Flags);
2716}
2717
2719 SelectionDAG &DAG) const {
2720 SDValue X = Op.getOperand(0);
2721 EVT VT = Op.getValueType();
2722 SDNodeFlags Flags = Op->getFlags();
2723 SDLoc DL(Op);
2724 const bool IsLog10 = Op.getOpcode() == ISD::FLOG10;
2725 assert(IsLog10 || Op.getOpcode() == ISD::FLOG);
2726
2727 if (VT == MVT::f16 || Flags.hasApproximateFuncs()) {
2728 // TODO: The direct f16 path is 1.79 ulp for f16. This should be used
2729 // depending on !fpmath metadata.
2730
2731 bool PromoteToF32 = VT == MVT::f16 && (!Flags.hasApproximateFuncs() ||
2732 !isTypeLegal(MVT::f16));
2733
2734 if (PromoteToF32) {
2735 // Log and multiply in f32 is always good enough for f16.
2736 X = DAG.getNode(ISD::FP_EXTEND, DL, MVT::f32, X, Flags);
2737 }
2738
2739 SDValue Lowered = LowerFLOGUnsafe(X, DL, DAG, IsLog10, Flags);
2740 if (PromoteToF32) {
2741 return DAG.getNode(ISD::FP_ROUND, DL, VT, Lowered,
2742 DAG.getTargetConstant(0, DL, MVT::i32), Flags);
2743 }
2744
2745 return Lowered;
2746 }
2747
2748 SDValue ScaledInput, IsScaled;
2749 if (VT == MVT::f16)
2750 X = DAG.getNode(ISD::FP_EXTEND, DL, MVT::f32, X, Flags);
2751 else {
2752 std::tie(ScaledInput, IsScaled) = getScaledLogInput(DAG, DL, X, Flags);
2753 if (ScaledInput)
2754 X = ScaledInput;
2755 }
2756
2757 SDValue Y = DAG.getNode(AMDGPUISD::LOG, DL, VT, X, Flags);
2758
2759 SDValue R;
2760 if (Subtarget->hasFastFMAF32()) {
2761 // c+cc are ln(2)/ln(10) to more than 49 bits
2762 const float c_log10 = 0x1.344134p-2f;
2763 const float cc_log10 = 0x1.09f79ep-26f;
2764
2765 // c + cc is ln(2) to more than 49 bits
2766 const float c_log = 0x1.62e42ep-1f;
2767 const float cc_log = 0x1.efa39ep-25f;
2768
2769 SDValue C = DAG.getConstantFP(IsLog10 ? c_log10 : c_log, DL, VT);
2770 SDValue CC = DAG.getConstantFP(IsLog10 ? cc_log10 : cc_log, DL, VT);
2771 // This adds correction terms for which contraction may lead to an increase
2772 // in the error of the approximation, so disable it.
2773 Flags.setAllowContract(false);
2774 R = DAG.getNode(ISD::FMUL, DL, VT, Y, C, Flags);
2775 SDValue NegR = DAG.getNode(ISD::FNEG, DL, VT, R, Flags);
2776 SDValue FMA0 = DAG.getNode(ISD::FMA, DL, VT, Y, C, NegR, Flags);
2777 SDValue FMA1 = DAG.getNode(ISD::FMA, DL, VT, Y, CC, FMA0, Flags);
2778 R = DAG.getNode(ISD::FADD, DL, VT, R, FMA1, Flags);
2779 } else {
2780 // ch+ct is ln(2)/ln(10) to more than 36 bits
2781 const float ch_log10 = 0x1.344000p-2f;
2782 const float ct_log10 = 0x1.3509f6p-18f;
2783
2784 // ch + ct is ln(2) to more than 36 bits
2785 const float ch_log = 0x1.62e000p-1f;
2786 const float ct_log = 0x1.0bfbe8p-15f;
2787
2788 SDValue CH = DAG.getConstantFP(IsLog10 ? ch_log10 : ch_log, DL, VT);
2789 SDValue CT = DAG.getConstantFP(IsLog10 ? ct_log10 : ct_log, DL, VT);
2790
2791 SDValue YAsInt = DAG.getNode(ISD::BITCAST, DL, MVT::i32, Y);
2792 SDValue MaskConst = DAG.getConstant(0xfffff000, DL, MVT::i32);
2793 SDValue YHInt = DAG.getNode(ISD::AND, DL, MVT::i32, YAsInt, MaskConst);
2794 SDValue YH = DAG.getNode(ISD::BITCAST, DL, MVT::f32, YHInt);
2795 SDValue YT = DAG.getNode(ISD::FSUB, DL, VT, Y, YH, Flags);
2796 // This adds correction terms for which contraction may lead to an increase
2797 // in the error of the approximation, so disable it.
2798 Flags.setAllowContract(false);
2799 SDValue YTCT = DAG.getNode(ISD::FMUL, DL, VT, YT, CT, Flags);
2800 SDValue Mad0 = getMad(DAG, DL, VT, YH, CT, YTCT, Flags);
2801 SDValue Mad1 = getMad(DAG, DL, VT, YT, CH, Mad0, Flags);
2802 R = getMad(DAG, DL, VT, YH, CH, Mad1);
2803 }
2804
2805 const bool IsFiniteOnly = Flags.hasNoNaNs() && Flags.hasNoInfs();
2806
2807 // TODO: Check if known finite from source value.
2808 if (!IsFiniteOnly) {
2809 SDValue IsFinite = getIsFinite(DAG, Y, Flags);
2810 R = DAG.getNode(ISD::SELECT, DL, VT, IsFinite, R, Y, Flags);
2811 }
2812
2813 if (IsScaled) {
2814 SDValue Zero = DAG.getConstantFP(0.0f, DL, VT);
2815 SDValue ShiftK =
2816 DAG.getConstantFP(IsLog10 ? 0x1.344136p+3f : 0x1.62e430p+4f, DL, VT);
2817 SDValue Shift =
2818 DAG.getNode(ISD::SELECT, DL, VT, IsScaled, ShiftK, Zero, Flags);
2819 R = DAG.getNode(ISD::FSUB, DL, VT, R, Shift, Flags);
2820 }
2821
2822 return R;
2823}
2824
2825// Do f32 fast math expansion for flog2 or flog10. This is accurate enough for a
2826// promote f16 operation.
2828 SelectionDAG &DAG, bool IsLog10,
2829 SDNodeFlags Flags) const {
2830 EVT VT = Src.getValueType();
2831 unsigned LogOp =
2832 VT == MVT::f32 ? (unsigned)AMDGPUISD::LOG : (unsigned)ISD::FLOG2;
2833
2834 double Log2BaseInverted =
2836
2837 if (VT == MVT::f32) {
2838 auto [ScaledInput, IsScaled] = getScaledLogInput(DAG, SL, Src, Flags);
2839 if (ScaledInput) {
2840 SDValue LogSrc = DAG.getNode(AMDGPUISD::LOG, SL, VT, ScaledInput, Flags);
2841 SDValue ScaledResultOffset =
2842 DAG.getConstantFP(-32.0 * Log2BaseInverted, SL, VT);
2843
2844 SDValue Zero = DAG.getConstantFP(0.0f, SL, VT);
2845
2846 SDValue ResultOffset = DAG.getNode(ISD::SELECT, SL, VT, IsScaled,
2847 ScaledResultOffset, Zero, Flags);
2848
2849 SDValue Log2Inv = DAG.getConstantFP(Log2BaseInverted, SL, VT);
2850
2851 if (Subtarget->hasFastFMAF32())
2852 return DAG.getNode(ISD::FMA, SL, VT, LogSrc, Log2Inv, ResultOffset,
2853 Flags);
2854 SDValue Mul = DAG.getNode(ISD::FMUL, SL, VT, LogSrc, Log2Inv, Flags);
2855 return DAG.getNode(ISD::FADD, SL, VT, Mul, ResultOffset);
2856 }
2857 }
2858
2859 SDValue Log2Operand = DAG.getNode(LogOp, SL, VT, Src, Flags);
2860 SDValue Log2BaseInvertedOperand = DAG.getConstantFP(Log2BaseInverted, SL, VT);
2861
2862 return DAG.getNode(ISD::FMUL, SL, VT, Log2Operand, Log2BaseInvertedOperand,
2863 Flags);
2864}
2865
2866// This expansion gives a result slightly better than 1ulp.
2868 SelectionDAG &DAG) const {
2869 SDLoc DL(Op);
2870 SDValue X = Op.getOperand(0);
2871
2872 // TODO: Check if reassoc is safe. There is an output change in exp2 and
2873 // exp10, which slightly increases ulp.
2874 SDNodeFlags Flags = Op->getFlags() & ~SDNodeFlags::AllowReassociation;
2875
2876 SDValue DN, F, T;
2877
2878 if (Op.getOpcode() == ISD::FEXP2) {
2879 // dn = rint(x)
2880 DN = DAG.getNode(ISD::FRINT, DL, MVT::f64, X, Flags);
2881 // f = x - dn
2882 F = DAG.getNode(ISD::FSUB, DL, MVT::f64, X, DN, Flags);
2883 // t = f*C1 + f*C2
2884 SDValue C1 = DAG.getConstantFP(0x1.62e42fefa39efp-1, DL, MVT::f64);
2885 SDValue C2 = DAG.getConstantFP(0x1.abc9e3b39803fp-56, DL, MVT::f64);
2886 SDValue Mul2 = DAG.getNode(ISD::FMUL, DL, MVT::f64, F, C2, Flags);
2887 T = DAG.getNode(ISD::FMA, DL, MVT::f64, F, C1, Mul2, Flags);
2888 } else if (Op.getOpcode() == ISD::FEXP10) {
2889 // dn = rint(x * C1)
2890 SDValue C1 = DAG.getConstantFP(0x1.a934f0979a371p+1, DL, MVT::f64);
2891 SDValue Mul = DAG.getNode(ISD::FMUL, DL, MVT::f64, X, C1, Flags);
2892 DN = DAG.getNode(ISD::FRINT, DL, MVT::f64, Mul, Flags);
2893
2894 // f = FMA(-dn, C2, FMA(-dn, C3, x))
2895 SDValue NegDN = DAG.getNode(ISD::FNEG, DL, MVT::f64, DN, Flags);
2896 SDValue C2 = DAG.getConstantFP(-0x1.9dc1da994fd21p-59, DL, MVT::f64);
2897 SDValue C3 = DAG.getConstantFP(0x1.34413509f79ffp-2, DL, MVT::f64);
2898 SDValue Inner = DAG.getNode(ISD::FMA, DL, MVT::f64, NegDN, C3, X, Flags);
2899 F = DAG.getNode(ISD::FMA, DL, MVT::f64, NegDN, C2, Inner, Flags);
2900
2901 // t = FMA(f, C4, f*C5)
2902 SDValue C4 = DAG.getConstantFP(0x1.26bb1bbb55516p+1, DL, MVT::f64);
2903 SDValue C5 = DAG.getConstantFP(-0x1.f48ad494ea3e9p-53, DL, MVT::f64);
2904 SDValue MulF = DAG.getNode(ISD::FMUL, DL, MVT::f64, F, C5, Flags);
2905 T = DAG.getNode(ISD::FMA, DL, MVT::f64, F, C4, MulF, Flags);
2906 } else { // ISD::FEXP
2907 // dn = rint(x * C1)
2908 SDValue C1 = DAG.getConstantFP(0x1.71547652b82fep+0, DL, MVT::f64);
2909 SDValue Mul = DAG.getNode(ISD::FMUL, DL, MVT::f64, X, C1, Flags);
2910 DN = DAG.getNode(ISD::FRINT, DL, MVT::f64, Mul, Flags);
2911
2912 // t = FMA(-dn, C2, FMA(-dn, C3, x))
2913 SDValue NegDN = DAG.getNode(ISD::FNEG, DL, MVT::f64, DN, Flags);
2914 SDValue C2 = DAG.getConstantFP(0x1.abc9e3b39803fp-56, DL, MVT::f64);
2915 SDValue C3 = DAG.getConstantFP(0x1.62e42fefa39efp-1, DL, MVT::f64);
2916 SDValue Inner = DAG.getNode(ISD::FMA, DL, MVT::f64, NegDN, C3, X, Flags);
2917 T = DAG.getNode(ISD::FMA, DL, MVT::f64, NegDN, C2, Inner, Flags);
2918 }
2919
2920 // Polynomial expansion for p
2921 SDValue P = DAG.getConstantFP(0x1.ade156a5dcb37p-26, DL, MVT::f64);
2922 P = DAG.getNode(ISD::FMA, DL, MVT::f64, T, P,
2923 DAG.getConstantFP(0x1.28af3fca7ab0cp-22, DL, MVT::f64),
2924 Flags);
2925 P = DAG.getNode(ISD::FMA, DL, MVT::f64, T, P,
2926 DAG.getConstantFP(0x1.71dee623fde64p-19, DL, MVT::f64),
2927 Flags);
2928 P = DAG.getNode(ISD::FMA, DL, MVT::f64, T, P,
2929 DAG.getConstantFP(0x1.a01997c89e6b0p-16, DL, MVT::f64),
2930 Flags);
2931 P = DAG.getNode(ISD::FMA, DL, MVT::f64, T, P,
2932 DAG.getConstantFP(0x1.a01a014761f6ep-13, DL, MVT::f64),
2933 Flags);
2934 P = DAG.getNode(ISD::FMA, DL, MVT::f64, T, P,
2935 DAG.getConstantFP(0x1.6c16c1852b7b0p-10, DL, MVT::f64),
2936 Flags);
2937 P = DAG.getNode(ISD::FMA, DL, MVT::f64, T, P,
2938 DAG.getConstantFP(0x1.1111111122322p-7, DL, MVT::f64), Flags);
2939 P = DAG.getNode(ISD::FMA, DL, MVT::f64, T, P,
2940 DAG.getConstantFP(0x1.55555555502a1p-5, DL, MVT::f64), Flags);
2941 P = DAG.getNode(ISD::FMA, DL, MVT::f64, T, P,
2942 DAG.getConstantFP(0x1.5555555555511p-3, DL, MVT::f64), Flags);
2943 P = DAG.getNode(ISD::FMA, DL, MVT::f64, T, P,
2944 DAG.getConstantFP(0x1.000000000000bp-1, DL, MVT::f64), Flags);
2945
2946 SDValue One = DAG.getConstantFP(1.0, DL, MVT::f64);
2947
2948 P = DAG.getNode(ISD::FMA, DL, MVT::f64, T, P, One, Flags);
2949 P = DAG.getNode(ISD::FMA, DL, MVT::f64, T, P, One, Flags);
2950
2951 // z = ldexp(p, (int)dn)
2952 SDValue DNInt = DAG.getNode(ISD::FP_TO_SINT, DL, MVT::i32, DN);
2953 SDValue Z = DAG.getNode(ISD::FLDEXP, DL, MVT::f64, P, DNInt, Flags);
2954
2955 // Overflow/underflow guards
2956 SDValue CondHi = DAG.getSetCC(
2957 DL, MVT::i1, X, DAG.getConstantFP(1024.0, DL, MVT::f64), ISD::SETULE);
2958
2959 if (!Flags.hasNoInfs()) {
2960 SDValue PInf = DAG.getConstantFP(std::numeric_limits<double>::infinity(),
2961 DL, MVT::f64);
2962 Z = DAG.getSelect(DL, MVT::f64, CondHi, Z, PInf, Flags);
2963 }
2964
2965 SDValue CondLo = DAG.getSetCC(
2966 DL, MVT::i1, X, DAG.getConstantFP(-1075.0, DL, MVT::f64), ISD::SETUGE);
2967 SDValue Zero = DAG.getConstantFP(0.0, DL, MVT::f64);
2968 Z = DAG.getSelect(DL, MVT::f64, CondLo, Z, Zero, Flags);
2969
2970 return Z;
2971}
2972
2974 // v_exp_f32 is good enough for OpenCL, except it doesn't handle denormals.
2975 // If we have to handle denormals, scale up the input and adjust the result.
2976
2977 EVT VT = Op.getValueType();
2978 if (VT == MVT::f64)
2979 return lowerFEXPF64(Op, DAG);
2980
2981 SDLoc SL(Op);
2982 SDValue Src = Op.getOperand(0);
2983 SDNodeFlags Flags = Op->getFlags();
2984
2985 if (VT == MVT::f16) {
2986 // Nothing in half is a denormal when promoted to f32.
2987 assert(!isTypeLegal(MVT::f16));
2988 SDValue Ext = DAG.getNode(ISD::FP_EXTEND, SL, MVT::f32, Src, Flags);
2989 SDValue Log = DAG.getNode(AMDGPUISD::EXP, SL, MVT::f32, Ext, Flags);
2990 return DAG.getNode(ISD::FP_ROUND, SL, VT, Log,
2991 DAG.getTargetConstant(0, SL, MVT::i32), Flags);
2992 }
2993
2994 assert(VT == MVT::f32);
2995
2996 if (!needsDenormHandlingF32(DAG, Src, Flags))
2997 return DAG.getNode(AMDGPUISD::EXP, SL, MVT::f32, Src, Flags);
2998
2999 // bool needs_scaling = x < -0x1.f80000p+6f;
3000 // v_exp_f32(x + (s ? 0x1.0p+6f : 0.0f)) * (s ? 0x1.0p-64f : 1.0f);
3001
3002 // -nextafter(128.0, -1)
3003 SDValue RangeCheckConst = DAG.getConstantFP(-0x1.f80000p+6f, SL, VT);
3004
3005 EVT SetCCVT = getSetCCResultType(DAG.getDataLayout(), *DAG.getContext(), VT);
3006
3007 SDValue NeedsScaling =
3008 DAG.getSetCC(SL, SetCCVT, Src, RangeCheckConst, ISD::SETOLT);
3009
3010 SDValue SixtyFour = DAG.getConstantFP(0x1.0p+6f, SL, VT);
3011 SDValue Zero = DAG.getConstantFP(0.0, SL, VT);
3012
3013 SDValue AddOffset =
3014 DAG.getNode(ISD::SELECT, SL, VT, NeedsScaling, SixtyFour, Zero);
3015
3016 SDValue AddInput = DAG.getNode(ISD::FADD, SL, VT, Src, AddOffset, Flags);
3017 SDValue Exp2 = DAG.getNode(AMDGPUISD::EXP, SL, VT, AddInput, Flags);
3018
3019 SDValue TwoExpNeg64 = DAG.getConstantFP(0x1.0p-64f, SL, VT);
3020 SDValue One = DAG.getConstantFP(1.0, SL, VT);
3021 SDValue ResultScale =
3022 DAG.getNode(ISD::SELECT, SL, VT, NeedsScaling, TwoExpNeg64, One);
3023
3024 return DAG.getNode(ISD::FMUL, SL, VT, Exp2, ResultScale, Flags);
3025}
3026
3028 SelectionDAG &DAG,
3029 SDNodeFlags Flags,
3030 bool IsExp10) const {
3031 // exp(x) -> exp2(M_LOG2E_F * x);
3032 // exp10(x) -> exp2(log2(10) * x);
3033 EVT VT = X.getValueType();
3034 SDValue Const =
3035 DAG.getConstantFP(IsExp10 ? 0x1.a934f0p+1f : numbers::log2e, SL, VT);
3036
3037 SDValue Mul = DAG.getNode(ISD::FMUL, SL, VT, X, Const, Flags);
3038 return DAG.getNode(VT == MVT::f32 ? (unsigned)AMDGPUISD::EXP
3039 : (unsigned)ISD::FEXP2,
3040 SL, VT, Mul, Flags);
3041}
3042
3044 SelectionDAG &DAG,
3045 SDNodeFlags Flags) const {
3046 EVT VT = X.getValueType();
3047 if (VT != MVT::f32 || !needsDenormHandlingF32(DAG, X, Flags))
3048 return lowerFEXPUnsafeImpl(X, SL, DAG, Flags, /*IsExp10=*/false);
3049
3050 EVT SetCCVT = getSetCCResultType(DAG.getDataLayout(), *DAG.getContext(), VT);
3051
3052 SDValue Threshold = DAG.getConstantFP(-0x1.5d58a0p+6f, SL, VT);
3053 SDValue NeedsScaling = DAG.getSetCC(SL, SetCCVT, X, Threshold, ISD::SETOLT);
3054
3055 SDValue ScaleOffset = DAG.getConstantFP(0x1.0p+6f, SL, VT);
3056
3057 SDValue ScaledX = DAG.getNode(ISD::FADD, SL, VT, X, ScaleOffset, Flags);
3058
3059 SDValue AdjustedX =
3060 DAG.getNode(ISD::SELECT, SL, VT, NeedsScaling, ScaledX, X);
3061
3062 const SDValue Log2E = DAG.getConstantFP(numbers::log2e, SL, VT);
3063 SDValue ExpInput = DAG.getNode(ISD::FMUL, SL, VT, AdjustedX, Log2E, Flags);
3064
3065 SDValue Exp2 = DAG.getNode(AMDGPUISD::EXP, SL, VT, ExpInput, Flags);
3066
3067 SDValue ResultScaleFactor = DAG.getConstantFP(0x1.969d48p-93f, SL, VT);
3068 SDValue AdjustedResult =
3069 DAG.getNode(ISD::FMUL, SL, VT, Exp2, ResultScaleFactor, Flags);
3070
3071 return DAG.getNode(ISD::SELECT, SL, VT, NeedsScaling, AdjustedResult, Exp2,
3072 Flags);
3073}
3074
3075/// Emit approx-funcs appropriate lowering for exp10. inf/nan should still be
3076/// handled correctly.
3078 SelectionDAG &DAG,
3079 SDNodeFlags Flags) const {
3080 const EVT VT = X.getValueType();
3081
3082 const unsigned Exp2Op = VT == MVT::f32 ? static_cast<unsigned>(AMDGPUISD::EXP)
3083 : static_cast<unsigned>(ISD::FEXP2);
3084
3085 if (VT != MVT::f32 || !needsDenormHandlingF32(DAG, X, Flags)) {
3086 // exp2(x * 0x1.a92000p+1f) * exp2(x * 0x1.4f0978p-11f);
3087 SDValue K0 = DAG.getConstantFP(0x1.a92000p+1f, SL, VT);
3088 SDValue K1 = DAG.getConstantFP(0x1.4f0978p-11f, SL, VT);
3089
3090 SDValue Mul0 = DAG.getNode(ISD::FMUL, SL, VT, X, K0, Flags);
3091 SDValue Exp2_0 = DAG.getNode(Exp2Op, SL, VT, Mul0, Flags);
3092 SDValue Mul1 = DAG.getNode(ISD::FMUL, SL, VT, X, K1, Flags);
3093 SDValue Exp2_1 = DAG.getNode(Exp2Op, SL, VT, Mul1, Flags);
3094 return DAG.getNode(ISD::FMUL, SL, VT, Exp2_0, Exp2_1);
3095 }
3096
3097 // bool s = x < -0x1.2f7030p+5f;
3098 // x += s ? 0x1.0p+5f : 0.0f;
3099 // exp10 = exp2(x * 0x1.a92000p+1f) *
3100 // exp2(x * 0x1.4f0978p-11f) *
3101 // (s ? 0x1.9f623ep-107f : 1.0f);
3102
3103 EVT SetCCVT = getSetCCResultType(DAG.getDataLayout(), *DAG.getContext(), VT);
3104
3105 SDValue Threshold = DAG.getConstantFP(-0x1.2f7030p+5f, SL, VT);
3106 SDValue NeedsScaling = DAG.getSetCC(SL, SetCCVT, X, Threshold, ISD::SETOLT);
3107
3108 SDValue ScaleOffset = DAG.getConstantFP(0x1.0p+5f, SL, VT);
3109 SDValue ScaledX = DAG.getNode(ISD::FADD, SL, VT, X, ScaleOffset, Flags);
3110 SDValue AdjustedX =
3111 DAG.getNode(ISD::SELECT, SL, VT, NeedsScaling, ScaledX, X);
3112
3113 SDValue K0 = DAG.getConstantFP(0x1.a92000p+1f, SL, VT);
3114 SDValue K1 = DAG.getConstantFP(0x1.4f0978p-11f, SL, VT);
3115
3116 SDValue Mul0 = DAG.getNode(ISD::FMUL, SL, VT, AdjustedX, K0, Flags);
3117 SDValue Exp2_0 = DAG.getNode(Exp2Op, SL, VT, Mul0, Flags);
3118 SDValue Mul1 = DAG.getNode(ISD::FMUL, SL, VT, AdjustedX, K1, Flags);
3119 SDValue Exp2_1 = DAG.getNode(Exp2Op, SL, VT, Mul1, Flags);
3120
3121 SDValue MulExps = DAG.getNode(ISD::FMUL, SL, VT, Exp2_0, Exp2_1, Flags);
3122
3123 SDValue ResultScaleFactor = DAG.getConstantFP(0x1.9f623ep-107f, SL, VT);
3124 SDValue AdjustedResult =
3125 DAG.getNode(ISD::FMUL, SL, VT, MulExps, ResultScaleFactor, Flags);
3126
3127 return DAG.getNode(ISD::SELECT, SL, VT, NeedsScaling, AdjustedResult, MulExps,
3128 Flags);
3129}
3130
3132 EVT VT = Op.getValueType();
3133
3134 if (VT == MVT::f64)
3135 return lowerFEXPF64(Op, DAG);
3136
3137 SDLoc SL(Op);
3138 SDValue X = Op.getOperand(0);
3139 SDNodeFlags Flags = Op->getFlags();
3140 const bool IsExp10 = Op.getOpcode() == ISD::FEXP10;
3141
3142 // TODO: Interpret allowApproxFunc as ignoring DAZ. This is currently copying
3143 // library behavior. Also, is known-not-daz source sufficient?
3144 if (allowApproxFunc(DAG, Flags)) { // TODO: Does this really require fast?
3145 return IsExp10 ? lowerFEXP10Unsafe(X, SL, DAG, Flags)
3146 : lowerFEXPUnsafe(X, SL, DAG, Flags);
3147 }
3148
3149 if (VT.getScalarType() == MVT::f16) {
3150 if (VT.isVector())
3151 return SDValue();
3152
3153 // Nothing in half is a denormal when promoted to f32.
3154 //
3155 // exp(f16 x) ->
3156 // fptrunc (v_exp_f32 (fmul (fpext x), log2e))
3157 //
3158 // exp10(f16 x) ->
3159 // fptrunc (v_exp_f32 (fmul (fpext x), log2(10)))
3160 SDValue Ext = DAG.getNode(ISD::FP_EXTEND, SL, MVT::f32, X, Flags);
3161 SDValue Lowered = lowerFEXPUnsafeImpl(Ext, SL, DAG, Flags, IsExp10);
3162 return DAG.getNode(ISD::FP_ROUND, SL, VT, Lowered,
3163 DAG.getTargetConstant(0, SL, MVT::i32), Flags);
3164 }
3165
3166 assert(VT == MVT::f32);
3167
3168 // Algorithm:
3169 //
3170 // e^x = 2^(x/ln(2)) = 2^(x*(64/ln(2))/64)
3171 //
3172 // x*(64/ln(2)) = n + f, |f| <= 0.5, n is integer
3173 // n = 64*m + j, 0 <= j < 64
3174 //
3175 // e^x = 2^((64*m + j + f)/64)
3176 // = (2^m) * (2^(j/64)) * 2^(f/64)
3177 // = (2^m) * (2^(j/64)) * e^(f*(ln(2)/64))
3178 //
3179 // f = x*(64/ln(2)) - n
3180 // r = f*(ln(2)/64) = x - n*(ln(2)/64)
3181 //
3182 // e^x = (2^m) * (2^(j/64)) * e^r
3183 //
3184 // (2^(j/64)) is precomputed
3185 //
3186 // e^r = 1 + r + (r^2)/2! + (r^3)/3! + (r^4)/4! + (r^5)/5!
3187 // e^r = 1 + q
3188 //
3189 // q = r + (r^2)/2! + (r^3)/3! + (r^4)/4! + (r^5)/5!
3190 //
3191 // e^x = (2^m) * ( (2^(j/64)) + q*(2^(j/64)) )
3192 SDNodeFlags FlagsNoContract = Flags;
3193 FlagsNoContract.setAllowContract(false);
3194
3195 SDValue PH, PL;
3196 if (Subtarget->hasFastFMAF32()) {
3197 const float c_exp = numbers::log2ef;
3198 const float cc_exp = 0x1.4ae0bep-26f; // c+cc are 49 bits
3199 const float c_exp10 = 0x1.a934f0p+1f;
3200 const float cc_exp10 = 0x1.2f346ep-24f;
3201
3202 SDValue C = DAG.getConstantFP(IsExp10 ? c_exp10 : c_exp, SL, VT);
3203 SDValue CC = DAG.getConstantFP(IsExp10 ? cc_exp10 : cc_exp, SL, VT);
3204
3205 PH = DAG.getNode(ISD::FMUL, SL, VT, X, C, Flags);
3206 SDValue NegPH = DAG.getNode(ISD::FNEG, SL, VT, PH, Flags);
3207 SDValue FMA0 = DAG.getNode(ISD::FMA, SL, VT, X, C, NegPH, Flags);
3208 PL = DAG.getNode(ISD::FMA, SL, VT, X, CC, FMA0, Flags);
3209 } else {
3210 const float ch_exp = 0x1.714000p+0f;
3211 const float cl_exp = 0x1.47652ap-12f; // ch + cl are 36 bits
3212
3213 const float ch_exp10 = 0x1.a92000p+1f;
3214 const float cl_exp10 = 0x1.4f0978p-11f;
3215
3216 SDValue CH = DAG.getConstantFP(IsExp10 ? ch_exp10 : ch_exp, SL, VT);
3217 SDValue CL = DAG.getConstantFP(IsExp10 ? cl_exp10 : cl_exp, SL, VT);
3218
3219 SDValue XAsInt = DAG.getNode(ISD::BITCAST, SL, MVT::i32, X);
3220 SDValue MaskConst = DAG.getConstant(0xfffff000, SL, MVT::i32);
3221 SDValue XHAsInt = DAG.getNode(ISD::AND, SL, MVT::i32, XAsInt, MaskConst);
3222 SDValue XH = DAG.getNode(ISD::BITCAST, SL, VT, XHAsInt);
3223 SDValue XL = DAG.getNode(ISD::FSUB, SL, VT, X, XH, Flags);
3224
3225 PH = DAG.getNode(ISD::FMUL, SL, VT, XH, CH, Flags);
3226
3227 SDValue XLCL = DAG.getNode(ISD::FMUL, SL, VT, XL, CL, Flags);
3228 SDValue Mad0 = getMad(DAG, SL, VT, XL, CH, XLCL, Flags);
3229 PL = getMad(DAG, SL, VT, XH, CL, Mad0, Flags);
3230 }
3231
3232 SDValue E = DAG.getNode(ISD::FROUNDEVEN, SL, VT, PH, Flags);
3233
3234 // It is unsafe to contract this fsub into the PH multiply.
3235 SDValue PHSubE = DAG.getNode(ISD::FSUB, SL, VT, PH, E, FlagsNoContract);
3236
3237 SDValue A = DAG.getNode(ISD::FADD, SL, VT, PHSubE, PL, Flags);
3238 SDValue IntE = DAG.getNode(ISD::FP_TO_SINT, SL, MVT::i32, E);
3239 SDValue Exp2 = DAG.getNode(AMDGPUISD::EXP, SL, VT, A, Flags);
3240
3241 SDValue R = DAG.getNode(ISD::FLDEXP, SL, VT, Exp2, IntE, Flags);
3242
3243 SDValue UnderflowCheckConst =
3244 DAG.getConstantFP(IsExp10 ? -0x1.66d3e8p+5f : -0x1.9d1da0p+6f, SL, VT);
3245
3246 EVT SetCCVT = getSetCCResultType(DAG.getDataLayout(), *DAG.getContext(), VT);
3247 SDValue Zero = DAG.getConstantFP(0.0, SL, VT);
3248 SDValue Underflow =
3249 DAG.getSetCC(SL, SetCCVT, X, UnderflowCheckConst, ISD::SETOLT);
3250
3251 R = DAG.getNode(ISD::SELECT, SL, VT, Underflow, Zero, R);
3252
3253 if (!Flags.hasNoInfs()) {
3254 SDValue OverflowCheckConst =
3255 DAG.getConstantFP(IsExp10 ? 0x1.344136p+5f : 0x1.62e430p+6f, SL, VT);
3256 SDValue Overflow =
3257 DAG.getSetCC(SL, SetCCVT, X, OverflowCheckConst, ISD::SETOGT);
3258 SDValue Inf =
3260 R = DAG.getNode(ISD::SELECT, SL, VT, Overflow, Inf, R);
3261 }
3262
3263 return R;
3264}
3265
3266// No pow instruction or libcall to fall back on. fmul_legacy returns 0 for a
3267// zero operand even against an infinity or a NaN, so pow(x, 0) and pow(1, y)
3268// fall out as exp2(0) = 1.
3270 EVT VT = Op.getValueType();
3271 assert(VT == MVT::f32);
3272
3273 SDLoc SL(Op);
3274 SDValue X = Op.getOperand(0);
3275 SDValue Y = Op.getOperand(1);
3276 SDNodeFlags Flags = Op->getFlags();
3277
3278 // log2(0) is -inf, which exp2 turns back into a finite result, so the core
3279 // goes infinite for inputs a ninf fpow still asserts about, like pow(0, 2).
3280 SDNodeFlags CoreFlags = Flags;
3281 CoreFlags.setNoInfs(false);
3282
3283 // Fast expansion: ignores denormals, NaN for a negative base.
3284 if (allowApproxFunc(DAG, Flags)) {
3285 SDValue Log = DAG.getNode(AMDGPUISD::LOG, SL, VT, X, CoreFlags);
3286 SDValue Mul =
3287 DAG.getNode(AMDGPUISD::FMUL_LEGACY, SL, VT, Y, Log, CoreFlags);
3288 return DAG.getNode(AMDGPUISD::EXP, SL, VT, Mul, CoreFlags);
3289 }
3290
3291 SDValue Abs = DAG.getNode(ISD::FABS, SL, VT, X, Flags);
3292 SDValue Log = DAG.getNode(ISD::FLOG2, SL, VT, Abs, CoreFlags);
3293 SDValue Mul = DAG.getNode(AMDGPUISD::FMUL_LEGACY, SL, VT, Y, Log, CoreFlags);
3294 SDValue R = DAG.getNode(ISD::FEXP2, SL, VT, Mul, CoreFlags);
3295
3296 // A base that is never negative needs neither the sign fixup nor the NaN.
3298 return R;
3299
3300 EVT SetCCVT = getSetCCResultType(DAG.getDataLayout(), *DAG.getContext(), VT);
3301
3302 // Infinities count as integers, and every f32 >= 2^24 in magnitude is even.
3303 SDValue YTrunc = DAG.getNode(ISD::FTRUNC, SL, VT, Y);
3304 SDValue YIsInt = DAG.getSetCC(SL, SetCCVT, YTrunc, Y, ISD::SETOEQ);
3305 SDValue YHalf =
3306 DAG.getNode(ISD::FMUL, SL, VT, Y, DAG.getConstantFP(0.5, SL, VT));
3307 SDValue YHalfTrunc = DAG.getNode(ISD::FTRUNC, SL, VT, YHalf);
3308 SDValue YIsOdd =
3309 DAG.getNode(ISD::AND, SL, SetCCVT, YIsInt,
3310 DAG.getSetCC(SL, SetCCVT, YHalfTrunc, YHalf, ISD::SETONE));
3311
3312 // pow(-x, odd y) = -pow(x, y). Selecting the copysign lets even y fold it.
3313 R = DAG.getNode(ISD::SELECT, SL, VT, YIsOdd,
3314 DAG.getNode(ISD::FCOPYSIGN, SL, VT, R, X), R);
3315
3316 if (Flags.hasNoNaNs())
3317 return R;
3318
3319 // A negative finite base to a non-integral power is NaN. -inf is excluded:
3320 // the core already gives pow(+inf, y). So are subnormals when flushed.
3321 FPClassTest NegFiniteMask = fcNegNormal;
3322 if (!DAG.getMachineFunction()
3324 .inputsAreZero())
3325 NegFiniteMask |= fcNegSubnormal;
3326 SDValue XNegFinite =
3327 DAG.getNode(ISD::IS_FPCLASS, SL, SetCCVT, X,
3328 DAG.getTargetConstant(NegFiniteMask, SL, MVT::i32));
3329 // Not a SETONE compare: pow(-1, NaN) needs the NaN-true behavior of !SETOEQ.
3330 SDValue NegNonInt = DAG.getNode(ISD::AND, SL, SetCCVT, XNegFinite,
3331 DAG.getNOT(SL, YIsInt, SetCCVT));
3332 SDValue NaN =
3334 return DAG.getNode(ISD::SELECT, SL, VT, NegNonInt, NaN, R);
3335}
3336
3337static bool isCtlzOpc(unsigned Opc) {
3338 return Opc == ISD::CTLZ || Opc == ISD::CTLZ_ZERO_POISON;
3339}
3340
3341static bool isCttzOpc(unsigned Opc) {
3342 return Opc == ISD::CTTZ || Opc == ISD::CTTZ_ZERO_POISON;
3343}
3344
3346 SelectionDAG &DAG) const {
3347 auto SL = SDLoc(Op);
3348 auto Opc = Op.getOpcode();
3349 auto Arg = Op.getOperand(0u);
3350 auto ResultVT = Op.getValueType();
3351
3352 if (ResultVT != MVT::i8 && ResultVT != MVT::i16)
3353 return {};
3354
3356 assert(ResultVT == Arg.getValueType());
3357
3358 const uint64_t NumBits = ResultVT.getFixedSizeInBits();
3359 SDValue NumExtBits = DAG.getConstant(32u - NumBits, SL, MVT::i32);
3360 SDValue NewOp;
3361
3362 if (Opc == ISD::CTLZ_ZERO_POISON) {
3363 NewOp = DAG.getNode(ISD::ANY_EXTEND, SL, MVT::i32, Arg);
3364 NewOp = DAG.getNode(ISD::SHL, SL, MVT::i32, NewOp, NumExtBits);
3365 NewOp = DAG.getNode(Opc, SL, MVT::i32, NewOp);
3366 } else {
3367 NewOp = DAG.getNode(ISD::ZERO_EXTEND, SL, MVT::i32, Arg);
3368 NewOp = DAG.getNode(Opc, SL, MVT::i32, NewOp);
3369 NewOp = DAG.getNode(ISD::SUB, SL, MVT::i32, NewOp, NumExtBits);
3370 }
3371
3372 return DAG.getNode(ISD::TRUNCATE, SL, ResultVT, NewOp);
3373}
3374
3376 SDLoc SL(Op);
3377 SDValue Src = Op.getOperand(0);
3378
3379 assert(isCtlzOpc(Op.getOpcode()) || isCttzOpc(Op.getOpcode()));
3380 bool Ctlz = isCtlzOpc(Op.getOpcode());
3381 unsigned NewOpc = Ctlz ? AMDGPUISD::FFBH_U32 : AMDGPUISD::FFBL_B32;
3382
3383 bool ZeroUndef = Op.getOpcode() == ISD::CTLZ_ZERO_POISON ||
3384 Op.getOpcode() == ISD::CTTZ_ZERO_POISON;
3385 bool Is64BitScalar = !Src->isDivergent() && Src.getValueType() == MVT::i64;
3386
3387 if (Src.getValueType() == MVT::i32 || Is64BitScalar) {
3388 // (ctlz hi:lo) -> (umin (ffbh src), 32)
3389 // (cttz hi:lo) -> (umin (ffbl src), 32)
3390 // (ctlz_zero_poison src) -> (ffbh src)
3391 // (cttz_zero_poison src) -> (ffbl src)
3392
3393 // 64-bit scalar version produce 32-bit result
3394 // (ctlz hi:lo) -> (umin (S_FLBIT_I32_B64 src), 64)
3395 // (cttz hi:lo) -> (umin (S_FF1_I32_B64 src), 64)
3396 // (ctlz_zero_poison src) -> (S_FLBIT_I32_B64 src)
3397 // (cttz_zero_poison src) -> (S_FF1_I32_B64 src)
3398 SDValue NewOpr = DAG.getNode(NewOpc, SL, MVT::i32, Src);
3399 if (!ZeroUndef) {
3400 const SDValue ConstVal = DAG.getConstant(
3401 Op.getValueType().getScalarSizeInBits(), SL, MVT::i32);
3402 NewOpr = DAG.getNode(ISD::UMIN, SL, MVT::i32, NewOpr, ConstVal);
3403 }
3404 return DAG.getNode(ISD::ZERO_EXTEND, SL, Src.getValueType(), NewOpr);
3405 }
3406
3407 SDValue Lo, Hi;
3408 std::tie(Lo, Hi) = split64BitValue(Src, DAG);
3409
3410 SDValue OprLo = DAG.getNode(NewOpc, SL, MVT::i32, Lo);
3411 SDValue OprHi = DAG.getNode(NewOpc, SL, MVT::i32, Hi);
3412
3413 // (ctlz hi:lo) -> (umin3 (ffbh hi), (uaddsat (ffbh lo), 32), 64)
3414 // (cttz hi:lo) -> (umin3 (uaddsat (ffbl hi), 32), (ffbl lo), 64)
3415 // (ctlz_zero_poison hi:lo) -> (umin (ffbh hi), (add (ffbh lo), 32))
3416 // (cttz_zero_poison hi:lo) -> (umin (add (ffbl hi), 32), (ffbl lo))
3417
3418 unsigned AddOpc = ZeroUndef ? ISD::ADD : ISD::UADDSAT;
3419 const SDValue Const32 = DAG.getConstant(32, SL, MVT::i32);
3420 if (Ctlz)
3421 OprLo = DAG.getNode(AddOpc, SL, MVT::i32, OprLo, Const32);
3422 else
3423 OprHi = DAG.getNode(AddOpc, SL, MVT::i32, OprHi, Const32);
3424
3425 SDValue NewOpr;
3426 NewOpr = DAG.getNode(ISD::UMIN, SL, MVT::i32, OprLo, OprHi);
3427 if (!ZeroUndef) {
3428 const SDValue Const64 = DAG.getConstant(64, SL, MVT::i32);
3429 NewOpr = DAG.getNode(ISD::UMIN, SL, MVT::i32, NewOpr, Const64);
3430 }
3431
3432 return DAG.getNode(ISD::ZERO_EXTEND, SL, MVT::i64, NewOpr);
3433}
3434
3436 SDLoc SL(Op);
3437 SDValue Src = Op.getOperand(0);
3438 assert(Src.getValueType() == MVT::i32 && "LowerCTLS only supports i32");
3439 SDValue Ffbh = DAG.getNode(
3440 ISD::INTRINSIC_WO_CHAIN, SL, MVT::i32,
3441 DAG.getTargetConstant(Intrinsic::amdgcn_sffbh, SL, MVT::i32), Src);
3442 SDValue Clamped = DAG.getNode(ISD::UMIN, SL, MVT::i32, Ffbh,
3443 DAG.getConstant(32, SL, MVT::i32));
3444 return DAG.getNode(ISD::ADD, SL, MVT::i32, Clamped,
3445 DAG.getAllOnesConstant(SL, MVT::i32));
3446}
3447
3449 EVT FP16Ty) const {
3450 assert(FP16Ty == MVT::f16 || FP16Ty == MVT::bf16);
3451 SDLoc SL(Op);
3452 SDValue Src = Op.getOperand(0);
3453 SDValue ToF32 = DAG.getNode(Op.getOpcode(), SL, MVT::f32, Src);
3454 SDValue FPRoundFlag = DAG.getIntPtrConstant(0, SL, /*isTarget=*/true);
3455 return DAG.getNode(ISD::FP_ROUND, SL, FP16Ty, ToF32, FPRoundFlag);
3456}
3457
3459 bool Signed) const {
3460 // The regular method converting a 64-bit integer to float roughly consists of
3461 // 2 steps: normalization and rounding. In fact, after normalization, the
3462 // conversion from a 64-bit integer to a float is essentially the same as the
3463 // one from a 32-bit integer. The only difference is that it has more
3464 // trailing bits to be rounded. To leverage the native 32-bit conversion, a
3465 // 64-bit integer could be preprocessed and fit into a 32-bit integer then
3466 // converted into the correct float number. The basic steps for the unsigned
3467 // conversion are illustrated in the following pseudo code:
3468 //
3469 // f32 uitofp(i64 u) {
3470 // i32 hi, lo = split(u);
3471 // // Only count the leading zeros in hi as we have native support of the
3472 // // conversion from i32 to f32. If hi is all 0s, the conversion is
3473 // // reduced to a 32-bit one automatically.
3474 // i32 shamt = clz(hi); // Return 32 if hi is all 0s.
3475 // u <<= shamt;
3476 // hi, lo = split(u);
3477 // hi |= (lo != 0) ? 1 : 0; // Adjust rounding bit in hi based on lo.
3478 // // convert it as a 32-bit integer and scale the result back.
3479 // return uitofp(hi) * 2^(32 - shamt);
3480 // }
3481 //
3482 // The signed one follows the same principle but uses 'ffbh_i32' to count its
3483 // sign bits instead. If 'ffbh_i32' is not available, its absolute value is
3484 // converted instead followed by negation based its sign bit.
3485
3486 SDLoc SL(Op);
3487 SDValue Src = Op.getOperand(0);
3488
3489 SDValue Lo, Hi;
3490 std::tie(Lo, Hi) = split64BitValue(Src, DAG);
3491 SDValue Sign;
3492 SDValue ShAmt;
3493 if (Signed && Subtarget->isGCN()) {
3494 // We also need to consider the sign bit in Lo if Hi has just sign bits,
3495 // i.e. Hi is 0 or -1. However, that only needs to take the MSB into
3496 // account. That is, the maximal shift is
3497 // - 32 if Lo and Hi have opposite signs;
3498 // - 33 if Lo and Hi have the same sign.
3499 //
3500 // Or, MaxShAmt = 33 + OppositeSign, where
3501 //
3502 // OppositeSign is defined as ((Lo ^ Hi) >> 31), which is
3503 // - -1 if Lo and Hi have opposite signs; and
3504 // - 0 otherwise.
3505 //
3506 // All in all, ShAmt is calculated as
3507 //
3508 // umin(sffbh(Hi), 33 + (Lo^Hi)>>31) - 1.
3509 //
3510 // or
3511 //
3512 // umin(sffbh(Hi) - 1, 32 + (Lo^Hi)>>31).
3513 //
3514 // to reduce the critical path.
3515 SDValue OppositeSign = DAG.getNode(
3516 ISD::SRA, SL, MVT::i32, DAG.getNode(ISD::XOR, SL, MVT::i32, Lo, Hi),
3517 DAG.getConstant(31, SL, MVT::i32));
3518 SDValue MaxShAmt =
3519 DAG.getNode(ISD::ADD, SL, MVT::i32, DAG.getConstant(32, SL, MVT::i32),
3520 OppositeSign);
3521 // Count the leading sign bits.
3522 ShAmt = DAG.getNode(
3523 ISD::INTRINSIC_WO_CHAIN, SL, MVT::i32,
3524 DAG.getTargetConstant(Intrinsic::amdgcn_sffbh, SL, MVT::i32), Hi);
3525 // Different from unsigned conversion, the shift should be one bit less to
3526 // preserve the sign bit.
3527 ShAmt = DAG.getNode(ISD::SUB, SL, MVT::i32, ShAmt,
3528 DAG.getConstant(1, SL, MVT::i32));
3529 ShAmt = DAG.getNode(ISD::UMIN, SL, MVT::i32, ShAmt, MaxShAmt);
3530 } else {
3531 if (Signed) {
3532 // Without 'ffbh_i32', only leading zeros could be counted. Take the
3533 // absolute value first.
3534 Sign = DAG.getNode(ISD::SRA, SL, MVT::i64, Src,
3535 DAG.getConstant(63, SL, MVT::i64));
3536 SDValue Abs =
3537 DAG.getNode(ISD::XOR, SL, MVT::i64,
3538 DAG.getNode(ISD::ADD, SL, MVT::i64, Src, Sign), Sign);
3539 std::tie(Lo, Hi) = split64BitValue(Abs, DAG);
3540 }
3541 // Count the leading zeros.
3542 ShAmt = DAG.getNode(ISD::CTLZ, SL, MVT::i32, Hi);
3543 // The shift amount for signed integers is [0, 32].
3544 }
3545 // Normalize the given 64-bit integer.
3546 SDValue Norm = DAG.getNode(ISD::SHL, SL, MVT::i64, Src, ShAmt);
3547 // Split it again.
3548 std::tie(Lo, Hi) = split64BitValue(Norm, DAG);
3549 // Calculate the adjust bit for rounding.
3550 // (lo != 0) ? 1 : 0 => (lo >= 1) ? 1 : 0 => umin(1, lo)
3551 SDValue Adjust = DAG.getNode(ISD::UMIN, SL, MVT::i32,
3552 DAG.getConstant(1, SL, MVT::i32), Lo);
3553 // Get the 32-bit normalized integer.
3554 Norm = DAG.getNode(ISD::OR, SL, MVT::i32, Hi, Adjust);
3555 // Convert the normalized 32-bit integer into f32.
3556
3557 bool UseLDEXP = isOperationLegal(ISD::FLDEXP, MVT::f32);
3558 unsigned Opc = Signed && UseLDEXP ? ISD::SINT_TO_FP : ISD::UINT_TO_FP;
3559 SDValue FVal = DAG.getNode(Opc, SL, MVT::f32, Norm);
3560
3561 // Finally, need to scale back the converted floating number as the original
3562 // 64-bit integer is converted as a 32-bit one.
3563 ShAmt = DAG.getNode(ISD::SUB, SL, MVT::i32, DAG.getConstant(32, SL, MVT::i32),
3564 ShAmt);
3565 // On GCN, use LDEXP directly.
3566 if (UseLDEXP)
3567 return DAG.getNode(ISD::FLDEXP, SL, MVT::f32, FVal, ShAmt);
3568
3569 // Otherwise, align 'ShAmt' to the exponent part and add it into the exponent
3570 // part directly to emulate the multiplication of 2^ShAmt. That 8-bit
3571 // exponent is enough to avoid overflowing into the sign bit.
3572 SDValue Exp = DAG.getNode(ISD::SHL, SL, MVT::i32, ShAmt,
3573 DAG.getConstant(23, SL, MVT::i32));
3574 SDValue IVal =
3575 DAG.getNode(ISD::ADD, SL, MVT::i32,
3576 DAG.getNode(ISD::BITCAST, SL, MVT::i32, FVal), Exp);
3577 if (Signed) {
3578 // Set the sign bit.
3579 Sign = DAG.getNode(ISD::SHL, SL, MVT::i32,
3580 DAG.getNode(ISD::TRUNCATE, SL, MVT::i32, Sign),
3581 DAG.getConstant(31, SL, MVT::i32));
3582 IVal = DAG.getNode(ISD::OR, SL, MVT::i32, IVal, Sign);
3583 }
3584 return DAG.getNode(ISD::BITCAST, SL, MVT::f32, IVal);
3585}
3586
3588 bool Signed) const {
3589 SDLoc SL(Op);
3590 SDValue Src = Op.getOperand(0);
3591
3592 SDValue Lo, Hi;
3593 std::tie(Lo, Hi) = split64BitValue(Src, DAG);
3594
3596 SL, MVT::f64, Hi);
3597
3598 SDValue CvtLo = DAG.getNode(ISD::UINT_TO_FP, SL, MVT::f64, Lo);
3599
3600 SDValue LdExp = DAG.getNode(ISD::FLDEXP, SL, MVT::f64, CvtHi,
3601 DAG.getConstant(32, SL, MVT::i32));
3602 // TODO: Should this propagate fast-math-flags?
3603 return DAG.getNode(ISD::FADD, SL, MVT::f64, LdExp, CvtLo);
3604}
3605
3607 bool Signed) const {
3608 EVT DestVT = Op.getValueType();
3609 SDValue Src = Op.getOperand(0);
3610 EVT SrcVT = Src.getValueType();
3611 unsigned ExtOpc = Signed ? ISD::SIGN_EXTEND : ISD::ZERO_EXTEND;
3612 unsigned CvtOpc = Signed ? ISD::SINT_TO_FP : ISD::UINT_TO_FP;
3613
3614 if (SrcVT == MVT::i16) {
3615 if (DestVT == MVT::f16)
3616 return Op;
3617
3618 SDLoc DL(Op);
3619 SDValue Ext = DAG.getNode(ExtOpc, DL, MVT::i32, Src);
3620 return DAG.getNode(CvtOpc, DL, DestVT, Ext);
3621 }
3622
3623 if (DestVT == MVT::bf16 || DestVT == MVT::f16)
3624 return LowerINT_TO_FP16(Op, DAG, DestVT);
3625
3626 if (SrcVT != MVT::i64)
3627 return Op;
3628
3629 if (DestVT == MVT::f32)
3630 return LowerINT_TO_FP32(Op, DAG, Signed);
3631
3632 assert(DestVT == MVT::f64);
3633 return LowerINT_TO_FP64(Op, DAG, Signed);
3634}
3635
3640
3645
3647 bool Signed) const {
3648 SDLoc SL(Op);
3649
3650 SDValue Src = Op.getOperand(0);
3651 EVT SrcVT = Src.getValueType();
3652
3653 assert(SrcVT == MVT::f32 || SrcVT == MVT::f64);
3654
3655 // The basic idea of converting a floating point number into a pair of 32-bit
3656 // integers is illustrated as follows:
3657 //
3658 // tf := trunc(val);
3659 // hif := floor(tf * 2^-32);
3660 // lof := tf - hif * 2^32; // lof is always positive due to floor.
3661 // hi := fptoi(hif);
3662 // lo := fptoi(lof);
3663 //
3664 SDValue Trunc = DAG.getNode(ISD::FTRUNC, SL, SrcVT, Src);
3665 SDValue Sign;
3666 if (Signed && SrcVT == MVT::f32) {
3667 // However, a 32-bit floating point number has only 23 bits mantissa and
3668 // it's not enough to hold all the significant bits of `lof` if val is
3669 // negative. To avoid the loss of precision, We need to take the absolute
3670 // value after truncating and flip the result back based on the original
3671 // signedness.
3672 Sign = DAG.getNode(ISD::SRA, SL, MVT::i32,
3673 DAG.getNode(ISD::BITCAST, SL, MVT::i32, Trunc),
3674 DAG.getConstant(31, SL, MVT::i32));
3675 Trunc = DAG.getNode(ISD::FABS, SL, SrcVT, Trunc);
3676 }
3677
3678 SDValue K0, K1;
3679 if (SrcVT == MVT::f64) {
3680 K0 = DAG.getConstantFP(
3681 llvm::bit_cast<double>(UINT64_C(/*2^-32*/ 0x3df0000000000000)), SL,
3682 SrcVT);
3683 K1 = DAG.getConstantFP(
3684 llvm::bit_cast<double>(UINT64_C(/*-2^32*/ 0xc1f0000000000000)), SL,
3685 SrcVT);
3686 } else {
3687 K0 = DAG.getConstantFP(
3688 llvm::bit_cast<float>(UINT32_C(/*2^-32*/ 0x2f800000)), SL, SrcVT);
3689 K1 = DAG.getConstantFP(
3690 llvm::bit_cast<float>(UINT32_C(/*-2^32*/ 0xcf800000)), SL, SrcVT);
3691 }
3692 // TODO: Should this propagate fast-math-flags?
3693 SDValue Mul = DAG.getNode(ISD::FMUL, SL, SrcVT, Trunc, K0);
3694
3695 SDValue FloorMul = DAG.getNode(ISD::FFLOOR, SL, SrcVT, Mul);
3696
3697 SDValue Fma = DAG.getNode(ISD::FMA, SL, SrcVT, FloorMul, K1, Trunc);
3698
3699 SDValue Hi = DAG.getNode((Signed && SrcVT == MVT::f64) ? ISD::FP_TO_SINT
3701 SL, MVT::i32, FloorMul);
3702 SDValue Lo = DAG.getNode(ISD::FP_TO_UINT, SL, MVT::i32, Fma);
3703
3704 SDValue Result = DAG.getNode(ISD::BITCAST, SL, MVT::i64,
3705 DAG.getBuildVector(MVT::v2i32, SL, {Lo, Hi}));
3706
3707 if (Signed && SrcVT == MVT::f32) {
3708 assert(Sign);
3709 // Flip the result based on the signedness, which is either all 0s or 1s.
3710 Sign = DAG.getNode(ISD::BITCAST, SL, MVT::i64,
3711 DAG.getBuildVector(MVT::v2i32, SL, {Sign, Sign}));
3712 // r := xor(r, sign) - sign;
3713 Result =
3714 DAG.getNode(ISD::SUB, SL, MVT::i64,
3715 DAG.getNode(ISD::XOR, SL, MVT::i64, Result, Sign), Sign);
3716 }
3717
3718 return Result;
3719}
3720
3722 SDLoc DL(Op);
3723 SDValue N0 = Op.getOperand(0);
3724
3725 // Convert to target node to get known bits
3726 if (N0.getValueType() == MVT::f32)
3727 return DAG.getNode(AMDGPUISD::FP_TO_FP16, DL, Op.getValueType(), N0);
3728
3729 if (Op->getFlags().hasApproximateFuncs()) {
3730 // There is a generic expand for FP_TO_FP16 with unsafe fast math.
3731 return SDValue();
3732 }
3733
3734 return LowerF64ToF16Safe(N0, DL, DAG);
3735}
3736
3737// return node in i32
3739 SelectionDAG &DAG) const {
3740 assert(Src.getSimpleValueType() == MVT::f64);
3741
3742 // f64 -> f16 conversion using round-to-nearest-even rounding mode.
3743 // TODO: We can generate better code for True16.
3744 const unsigned ExpMask = 0x7ff;
3745 const unsigned ExpBiasf64 = 1023;
3746 const unsigned ExpBiasf16 = 15;
3747 SDValue Zero = DAG.getConstant(0, DL, MVT::i32);
3748 SDValue One = DAG.getConstant(1, DL, MVT::i32);
3749 SDValue U = DAG.getNode(ISD::BITCAST, DL, MVT::i64, Src);
3750 SDValue UH = DAG.getNode(ISD::SRL, DL, MVT::i64, U,
3751 DAG.getConstant(32, DL, MVT::i64));
3752 UH = DAG.getZExtOrTrunc(UH, DL, MVT::i32);
3753 U = DAG.getZExtOrTrunc(U, DL, MVT::i32);
3754 SDValue E = DAG.getNode(ISD::SRL, DL, MVT::i32, UH,
3755 DAG.getConstant(20, DL, MVT::i64));
3756 E = DAG.getNode(ISD::AND, DL, MVT::i32, E,
3757 DAG.getConstant(ExpMask, DL, MVT::i32));
3758 // Subtract the fp64 exponent bias (1023) to get the real exponent and
3759 // add the f16 bias (15) to get the biased exponent for the f16 format.
3760 E = DAG.getNode(ISD::ADD, DL, MVT::i32, E,
3761 DAG.getConstant(-ExpBiasf64 + ExpBiasf16, DL, MVT::i32));
3762
3763 SDValue M = DAG.getNode(ISD::SRL, DL, MVT::i32, UH,
3764 DAG.getConstant(8, DL, MVT::i32));
3765 M = DAG.getNode(ISD::AND, DL, MVT::i32, M,
3766 DAG.getConstant(0xffe, DL, MVT::i32));
3767
3768 SDValue MaskedSig = DAG.getNode(ISD::AND, DL, MVT::i32, UH,
3769 DAG.getConstant(0x1ff, DL, MVT::i32));
3770 MaskedSig = DAG.getNode(ISD::OR, DL, MVT::i32, MaskedSig, U);
3771
3772 SDValue Lo40Set = DAG.getSelectCC(DL, MaskedSig, Zero, Zero, One, ISD::SETEQ);
3773 M = DAG.getNode(ISD::OR, DL, MVT::i32, M, Lo40Set);
3774
3775 // (M != 0 ? 0x0200 : 0) | 0x7c00;
3776 SDValue I = DAG.getNode(ISD::OR, DL, MVT::i32,
3777 DAG.getSelectCC(DL, M, Zero, DAG.getConstant(0x0200, DL, MVT::i32),
3778 Zero, ISD::SETNE), DAG.getConstant(0x7c00, DL, MVT::i32));
3779
3780 // N = M | (E << 12);
3781 SDValue N = DAG.getNode(ISD::OR, DL, MVT::i32, M,
3782 DAG.getNode(ISD::SHL, DL, MVT::i32, E,
3783 DAG.getConstant(12, DL, MVT::i32)));
3784
3785 // B = clamp(1-E, 0, 13);
3786 SDValue OneSubExp = DAG.getNode(ISD::SUB, DL, MVT::i32,
3787 One, E);
3788 SDValue B = DAG.getNode(ISD::SMAX, DL, MVT::i32, OneSubExp, Zero);
3789 B = DAG.getNode(ISD::SMIN, DL, MVT::i32, B,
3790 DAG.getConstant(13, DL, MVT::i32));
3791
3792 SDValue SigSetHigh = DAG.getNode(ISD::OR, DL, MVT::i32, M,
3793 DAG.getConstant(0x1000, DL, MVT::i32));
3794
3795 SDValue D = DAG.getNode(ISD::SRL, DL, MVT::i32, SigSetHigh, B);
3796 SDValue D0 = DAG.getNode(ISD::SHL, DL, MVT::i32, D, B);
3797 SDValue D1 = DAG.getSelectCC(DL, D0, SigSetHigh, One, Zero, ISD::SETNE);
3798 D = DAG.getNode(ISD::OR, DL, MVT::i32, D, D1);
3799
3800 SDValue V = DAG.getSelectCC(DL, E, One, D, N, ISD::SETLT);
3801 SDValue VLow3 = DAG.getNode(ISD::AND, DL, MVT::i32, V,
3802 DAG.getConstant(0x7, DL, MVT::i32));
3803 V = DAG.getNode(ISD::SRL, DL, MVT::i32, V,
3804 DAG.getConstant(2, DL, MVT::i32));
3805 SDValue V0 = DAG.getSelectCC(DL, VLow3, DAG.getConstant(3, DL, MVT::i32),
3806 One, Zero, ISD::SETEQ);
3807 SDValue V1 = DAG.getSelectCC(DL, VLow3, DAG.getConstant(5, DL, MVT::i32),
3808 One, Zero, ISD::SETGT);
3809 V1 = DAG.getNode(ISD::OR, DL, MVT::i32, V0, V1);
3810 V = DAG.getNode(ISD::ADD, DL, MVT::i32, V, V1);
3811
3812 V = DAG.getSelectCC(DL, E, DAG.getConstant(30, DL, MVT::i32),
3813 DAG.getConstant(0x7c00, DL, MVT::i32), V, ISD::SETGT);
3814 V = DAG.getSelectCC(DL, E, DAG.getConstant(1039, DL, MVT::i32),
3815 I, V, ISD::SETEQ);
3816
3817 // Extract the sign bit.
3818 SDValue Sign = DAG.getNode(ISD::SRL, DL, MVT::i32, UH,
3819 DAG.getConstant(16, DL, MVT::i32));
3820 Sign = DAG.getNode(ISD::AND, DL, MVT::i32, Sign,
3821 DAG.getConstant(0x8000, DL, MVT::i32));
3822
3823 return DAG.getNode(ISD::OR, DL, MVT::i32, Sign, V);
3824}
3825
3827 SelectionDAG &DAG) const {
3828 SDValue Src = Op.getOperand(0);
3829 unsigned OpOpcode = Op.getOpcode();
3830 EVT SrcVT = Src.getValueType();
3831 EVT DestVT = Op.getValueType();
3832
3833 // Will be selected natively
3834 if (SrcVT == MVT::f16 && DestVT == MVT::i16)
3835 return Op;
3836
3837 if (SrcVT == MVT::bf16 || (SrcVT == MVT::f16 && DestVT == MVT::i32)) {
3838 SDLoc DL(Op);
3839 SDValue PromotedSrc = DAG.getNode(ISD::FP_EXTEND, DL, MVT::f32, Src);
3840 return DAG.getNode(Op.getOpcode(), DL, DestVT, PromotedSrc);
3841 }
3842
3843 // Promote i16 to i32
3844 if (DestVT == MVT::i16 && (SrcVT == MVT::f32 || SrcVT == MVT::f64)) {
3845 SDLoc DL(Op);
3846
3847 SDValue FpToInt32 = DAG.getNode(OpOpcode, DL, MVT::i32, Src);
3848 return DAG.getNode(ISD::TRUNCATE, DL, MVT::i16, FpToInt32);
3849 }
3850
3851 if (DestVT != MVT::i64)
3852 return Op;
3853
3854 if (SrcVT == MVT::f16 ||
3855 (SrcVT == MVT::f32 && Src.getOpcode() == ISD::FP16_TO_FP)) {
3856 SDLoc DL(Op);
3857
3858 SDValue FpToInt32 = DAG.getNode(OpOpcode, DL, MVT::i32, Src);
3859 unsigned Ext =
3861 return DAG.getNode(Ext, DL, MVT::i64, FpToInt32);
3862 }
3863
3864 if (SrcVT == MVT::f32 || SrcVT == MVT::f64)
3865 return LowerFP_TO_INT64(Op, DAG, OpOpcode == ISD::FP_TO_SINT);
3866
3867 return SDValue();
3868}
3869
3871 SelectionDAG &DAG) const {
3872 SDValue Src = Op.getOperand(0);
3873 unsigned OpOpcode = Op.getOpcode();
3874 EVT SrcVT = Src.getValueType();
3875 EVT DstVT = Op.getValueType();
3876 SDValue SatVTOp = Op.getNode()->getOperand(1);
3877 EVT SatVT = cast<VTSDNode>(SatVTOp)->getVT();
3878 SDLoc DL(Op);
3879
3880 uint64_t DstWidth = DstVT.getScalarSizeInBits();
3881 uint64_t SatWidth = SatVT.getScalarSizeInBits();
3882 assert(SatWidth <= DstWidth && "Saturation width cannot exceed result width");
3883
3884 // Scalar cases will be selected natively to v_cvt_/s_cvt_ instructions.
3885 // v2f32 -> v2i16 will be selected natively to v_cvt_pk_[iu]16_f32.
3886 if (SatWidth == DstWidth) {
3887 if ((DstVT == MVT::i32 && (SrcVT == MVT::f32 || SrcVT == MVT::f64)) ||
3888 (DstVT == MVT::i16 && (SrcVT == MVT::f16 || SrcVT == MVT::f32)) ||
3889 (DstVT == MVT::v2i16 && SrcVT == MVT::v2f32))
3890 return Op;
3891 }
3892
3893 // Vectors can only be selected natively.
3894 if (DstVT.isVector())
3895 return SDValue();
3896
3897 // Perform all saturation at selected width (i16 or i32) and truncate
3898 if (SatWidth < DstWidth && SatWidth <= 32) {
3899 // For f16 conversion with sub-i16 saturation perform saturation
3900 // at i16, if available in the target. This removes the need for extra f16
3901 // to f32 conversion. For all the others use i32.
3902 MVT ResultVT =
3903 Subtarget->has16BitInsts() && SrcVT == MVT::f16 && SatWidth < 16
3904 ? MVT::i16
3905 : MVT::i32;
3906
3907 const SDValue ResultVTOp = DAG.getValueType(ResultVT);
3908 const uint64_t ResultWidth = ResultVT.getScalarSizeInBits();
3909
3910 // First, convert input float into selected integer (i16 or i32)
3911 SDValue FpToInt = DAG.getNode(OpOpcode, DL, ResultVT, Src, ResultVTOp);
3912 SDValue IntSatVal;
3913
3914 // Then, clamp at the saturation width using either i16 or i32 instructions
3915 if (OpOpcode == ISD::FP_TO_SINT_SAT) {
3916 SDValue MinConst = DAG.getConstant(
3917 APInt::getSignedMaxValue(SatWidth).sext(ResultWidth), DL, ResultVT);
3918 SDValue MaxConst = DAG.getConstant(
3919 APInt::getSignedMinValue(SatWidth).sext(ResultWidth), DL, ResultVT);
3920 SDValue MinVal = DAG.getNode(ISD::SMIN, DL, ResultVT, FpToInt, MinConst);
3921 IntSatVal = DAG.getNode(ISD::SMAX, DL, ResultVT, MinVal, MaxConst);
3922 } else {
3923 SDValue MinConst = DAG.getConstant(
3924 APInt::getMaxValue(SatWidth).zext(ResultWidth), DL, ResultVT);
3925 IntSatVal = DAG.getNode(ISD::UMIN, DL, ResultVT, FpToInt, MinConst);
3926 }
3927
3928 // Finally, after saturating at i16 or i32 fit into the destination type
3929 return DAG.getExtOrTrunc(OpOpcode == ISD::FP_TO_SINT_SAT, IntSatVal, DL,
3930 DstVT);
3931 }
3932
3933 // SatWidth == DstWidth or SatWidth > 32
3934
3935 // Saturate at i32 for i64 dst and f16/bf16 src (will invoke f16 promotion
3936 // below)
3937 if (DstVT == MVT::i64 &&
3938 (SrcVT == MVT::f16 || SrcVT == MVT::bf16 ||
3939 (SrcVT == MVT::f32 && Src.getOpcode() == ISD::FP16_TO_FP))) {
3940 const SDValue Int32VTOp = DAG.getValueType(MVT::i32);
3941 return DAG.getNode(OpOpcode, DL, DstVT, Src, Int32VTOp);
3942 }
3943
3944 // Promote f16/bf16 src to f32 for i32 conversion
3945 if (DstVT == MVT::i32 && (SrcVT == MVT::f16 || SrcVT == MVT::bf16)) {
3946 SDValue PromotedSrc = DAG.getNode(ISD::FP_EXTEND, DL, MVT::f32, Src);
3947 return DAG.getNode(Op.getOpcode(), DL, DstVT, PromotedSrc, SatVTOp);
3948 }
3949
3950 // For DstWidth < 16, promote i1 and i8 dst to i16 (if legal) with sub-i16
3951 // saturation. For DstWidth == 16, promote i16 dst to i32 with sub-i32
3952 // saturation; this covers i16.f32 and i16.f64
3953 if (DstWidth < 32) {
3954 // Note: this triggers SatWidth < DstWidth above to generate saturated
3955 // truncate by requesting MVT::i16/i32 destination with SatWidth < 16/32.
3956 MVT PromoteVT =
3957 (DstWidth < 16 && Subtarget->has16BitInsts()) ? MVT::i16 : MVT::i32;
3958 SDValue FpToInt = DAG.getNode(OpOpcode, DL, PromoteVT, Src, SatVTOp);
3959 return DAG.getNode(ISD::TRUNCATE, DL, DstVT, FpToInt);
3960 }
3961
3962 // TODO: can we implement i64 dst for f32/f64?
3963
3964 return SDValue();
3965}
3966
3968 SelectionDAG &DAG) const {
3969 EVT ExtraVT = cast<VTSDNode>(Op.getOperand(1))->getVT();
3970 MVT VT = Op.getSimpleValueType();
3971 MVT ScalarVT = VT.getScalarType();
3972
3973 assert(VT.isVector());
3974
3975 SDValue Src = Op.getOperand(0);
3976 SDLoc DL(Op);
3977
3978 // TODO: Don't scalarize on Evergreen?
3979 unsigned NElts = VT.getVectorNumElements();
3981 DAG.ExtractVectorElements(Src, Args, 0, NElts);
3982
3983 SDValue VTOp = DAG.getValueType(ExtraVT.getScalarType());
3984 for (unsigned I = 0; I < NElts; ++I)
3985 Args[I] = DAG.getNode(ISD::SIGN_EXTEND_INREG, DL, ScalarVT, Args[I], VTOp);
3986
3987 return DAG.getBuildVector(VT, DL, Args);
3988}
3989
3990//===----------------------------------------------------------------------===//
3991// Custom DAG optimizations
3992//===----------------------------------------------------------------------===//
3993
3994static bool isU24(SDValue Op, SelectionDAG &DAG) {
3995 return AMDGPUTargetLowering::numBitsUnsigned(Op, DAG) <= 24;
3996}
3997
3998static bool isI24(SDValue Op, SelectionDAG &DAG) {
3999 EVT VT = Op.getValueType();
4000 return VT.getSizeInBits() >= 24 && // Types less than 24-bit should be treated
4001 // as unsigned 24-bit values.
4003}
4004
4007 SelectionDAG &DAG = DCI.DAG;
4008 const TargetLowering &TLI = DAG.getTargetLoweringInfo();
4009 bool IsIntrin = Node24->getOpcode() == ISD::INTRINSIC_WO_CHAIN;
4010
4011 SDValue LHS = IsIntrin ? Node24->getOperand(1) : Node24->getOperand(0);
4012 SDValue RHS = IsIntrin ? Node24->getOperand(2) : Node24->getOperand(1);
4013 unsigned NewOpcode = Node24->getOpcode();
4014 if (IsIntrin) {
4015 unsigned IID = Node24->getConstantOperandVal(0);
4016 switch (IID) {
4017 case Intrinsic::amdgcn_mul_i24:
4018 NewOpcode = AMDGPUISD::MUL_I24;
4019 break;
4020 case Intrinsic::amdgcn_mul_u24:
4021 NewOpcode = AMDGPUISD::MUL_U24;
4022 break;
4023 case Intrinsic::amdgcn_mulhi_i24:
4024 NewOpcode = AMDGPUISD::MULHI_I24;
4025 break;
4026 case Intrinsic::amdgcn_mulhi_u24:
4027 NewOpcode = AMDGPUISD::MULHI_U24;
4028 break;
4029 default:
4030 llvm_unreachable("Expected 24-bit mul intrinsic");
4031 }
4032 }
4033
4034 APInt Demanded = APInt::getLowBitsSet(LHS.getValueSizeInBits(), 24);
4035
4037 return DAG.getConstant(0, SDLoc(Node24), Node24->getValueType(0));
4038
4039 // First try SimplifyDemandedBits which can simplify the nodes used by our
4040 // operands if this node is the only user.
4041 if (LHS.hasOneUse() && TLI.SimplifyDemandedBits(LHS, Demanded, DCI))
4042 return SDValue(Node24, 0);
4043 if (RHS.hasOneUse() && TLI.SimplifyDemandedBits(RHS, Demanded, DCI))
4044 return SDValue(Node24, 0);
4045
4046 // Then try SimplifyMultipleUseDemandedBits which allows the operands to have
4047 // other uses, but will only perform simplifications that involve bypassing
4048 // some nodes for this user.
4049 SDValue DemandedLHS = TLI.SimplifyMultipleUseDemandedBits(LHS, Demanded, DAG);
4050 SDValue DemandedRHS = TLI.SimplifyMultipleUseDemandedBits(RHS, Demanded, DAG);
4051 if (DemandedLHS || DemandedRHS)
4052 return DAG.getNode(NewOpcode, SDLoc(Node24), Node24->getVTList(),
4053 DemandedLHS ? DemandedLHS : LHS,
4054 DemandedRHS ? DemandedRHS : RHS);
4055
4056 return SDValue();
4057}
4058
4059template <typename IntTy>
4061 uint32_t Width, const SDLoc &DL) {
4062 if (Width + Offset < 32) {
4063 uint32_t Shl = static_cast<uint32_t>(Src0) << (32 - Offset - Width);
4064 IntTy Result = static_cast<IntTy>(Shl) >> (32 - Width);
4065 if constexpr (std::is_signed_v<IntTy>) {
4066 return DAG.getSignedConstant(Result, DL, MVT::i32);
4067 } else {
4068 return DAG.getConstant(Result, DL, MVT::i32);
4069 }
4070 }
4071
4072 return DAG.getConstant(Src0 >> Offset, DL, MVT::i32);
4073}
4074
4075static bool hasVolatileUser(SDNode *Val) {
4076 for (SDNode *U : Val->users()) {
4077 if (MemSDNode *M = dyn_cast<MemSDNode>(U)) {
4078 if (M->isVolatile())
4079 return true;
4080 }
4081 }
4082
4083 return false;
4084}
4085
4087 // i32 vectors are the canonical memory type.
4088 if (VT.getScalarType() == MVT::i32 || isTypeLegal(VT))
4089 return false;
4090
4091 if (!VT.isByteSized())
4092 return false;
4093
4094 unsigned Size = VT.getStoreSize();
4095
4096 if ((Size == 1 || Size == 2 || Size == 4) && !VT.isVector())
4097 return false;
4098
4099 if (Size == 3 || (Size > 4 && (Size % 4 != 0)))
4100 return false;
4101
4102 return true;
4103}
4104
4105// Replace load of an illegal type with a bitcast from a load of a friendlier
4106// type.
4108 DAGCombinerInfo &DCI) const {
4109 if (!DCI.isBeforeLegalize())
4110 return SDValue();
4111
4113 if (!LN->isSimple() || !ISD::isNormalLoad(LN) || hasVolatileUser(LN))
4114 return SDValue();
4115
4116 SDLoc SL(N);
4117 SelectionDAG &DAG = DCI.DAG;
4118 EVT VT = LN->getMemoryVT();
4119
4120 unsigned Size = VT.getStoreSize();
4121 Align Alignment = LN->getAlign();
4122 if (Alignment < Size && isTypeLegal(VT)) {
4123 unsigned IsFast;
4124 unsigned AS = LN->getAddressSpace();
4125
4126 // Expand unaligned loads earlier than legalization. Due to visitation order
4127 // problems during legalization, the emitted instructions to pack and unpack
4128 // the bytes again are not eliminated in the case of an unaligned copy.
4130 VT, AS, Alignment, LN->getMemOperand()->getFlags(), &IsFast)) {
4131 if (VT.isVector())
4132 return SplitVectorLoad(SDValue(LN, 0), DAG);
4133
4134 SDValue Ops[2];
4135 std::tie(Ops[0], Ops[1]) = expandUnalignedLoad(LN, DAG);
4136
4137 return DAG.getMergeValues(Ops, SDLoc(N));
4138 }
4139
4140 if (!IsFast)
4141 return SDValue();
4142 }
4143
4144 if (!shouldCombineMemoryType(VT))
4145 return SDValue();
4146
4147 EVT NewVT = getEquivalentMemType(*DAG.getContext(), VT);
4148
4149 SDValue NewLoad
4150 = DAG.getLoad(NewVT, SL, LN->getChain(),
4151 LN->getBasePtr(), LN->getMemOperand());
4152
4153 SDValue BC = DAG.getNode(ISD::BITCAST, SL, VT, NewLoad);
4154 DCI.CombineTo(N, BC, NewLoad.getValue(1));
4155 return SDValue(N, 0);
4156}
4157
4158// Replace store of an illegal type with a store of a bitcast to a friendlier
4159// type.
4161 DAGCombinerInfo &DCI) const {
4162 if (!DCI.isBeforeLegalize())
4163 return SDValue();
4164
4166 if (!SN->isSimple() || !ISD::isNormalStore(SN))
4167 return SDValue();
4168
4169 EVT VT = SN->getMemoryVT();
4170 unsigned Size = VT.getStoreSize();
4171
4172 SDLoc SL(N);
4173 SelectionDAG &DAG = DCI.DAG;
4174 Align Alignment = SN->getAlign();
4175 if (Alignment < Size && isTypeLegal(VT)) {
4176 unsigned IsFast;
4177 unsigned AS = SN->getAddressSpace();
4178
4179 // Expand unaligned stores earlier than legalization. Due to visitation
4180 // order problems during legalization, the emitted instructions to pack and
4181 // unpack the bytes again are not eliminated in the case of an unaligned
4182 // copy.
4184 VT, AS, Alignment, SN->getMemOperand()->getFlags(), &IsFast)) {
4185 if (VT.isVector())
4186 return SplitVectorStore(SDValue(SN, 0), DAG);
4187
4188 return expandUnalignedStore(SN, DAG);
4189 }
4190
4191 if (!IsFast)
4192 return SDValue();
4193 }
4194
4195 if (!shouldCombineMemoryType(VT))
4196 return SDValue();
4197
4198 EVT NewVT = getEquivalentMemType(*DAG.getContext(), VT);
4199 SDValue Val = SN->getValue();
4200
4201 // DCI.AddToWorklist(Val.getNode());
4202
4203 bool OtherUses = !Val.hasOneUse();
4204 SDValue CastVal = DAG.getBitcast(NewVT, Val);
4205 if (OtherUses) {
4206 SDValue CastBack = DAG.getBitcast(VT, CastVal);
4207 DAG.ReplaceAllUsesOfValueWith(Val, CastBack);
4208 }
4209
4210 return DAG.getStore(SN->getChain(), SL, CastVal,
4211 SN->getBasePtr(), SN->getMemOperand());
4212}
4213
4214// FIXME: This should go in generic DAG combiner with an isTruncateFree check,
4215// but isTruncateFree is inaccurate for i16 now because of SALU vs. VALU
4216// issues.
4218 DAGCombinerInfo &DCI) const {
4219 SelectionDAG &DAG = DCI.DAG;
4220 SDValue N0 = N->getOperand(0);
4221
4222 // (vt2 (assertzext (truncate vt0:x), vt1)) ->
4223 // (vt2 (truncate (assertzext vt0:x, vt1)))
4224 if (N0.getOpcode() == ISD::TRUNCATE) {
4225 SDValue N1 = N->getOperand(1);
4226 EVT ExtVT = cast<VTSDNode>(N1)->getVT();
4227 SDLoc SL(N);
4228
4229 SDValue Src = N0.getOperand(0);
4230 EVT SrcVT = Src.getValueType();
4231 if (SrcVT.bitsGE(ExtVT)) {
4232 SDValue NewInReg = DAG.getNode(N->getOpcode(), SL, SrcVT, Src, N1);
4233 return DAG.getNode(ISD::TRUNCATE, SL, N->getValueType(0), NewInReg);
4234 }
4235 }
4236
4237 return SDValue();
4238}
4239
4241 SDNode *N, DAGCombinerInfo &DCI) const {
4242 unsigned IID = N->getConstantOperandVal(0);
4243 switch (IID) {
4244 case Intrinsic::amdgcn_mul_i24:
4245 case Intrinsic::amdgcn_mul_u24:
4246 case Intrinsic::amdgcn_mulhi_i24:
4247 case Intrinsic::amdgcn_mulhi_u24:
4248 return simplifyMul24(N, DCI);
4249 case Intrinsic::amdgcn_fract:
4250 case Intrinsic::amdgcn_rsq:
4251 case Intrinsic::amdgcn_rcp_legacy:
4252 case Intrinsic::amdgcn_rsq_legacy:
4253 case Intrinsic::amdgcn_rsq_clamp:
4254 case Intrinsic::amdgcn_tanh:
4255 case Intrinsic::amdgcn_prng_b32: {
4256 // FIXME: This is probably wrong. If src is an sNaN, it won't be quieted
4257 SDValue Src = N->getOperand(1);
4258 return Src.isUndef() ? Src : SDValue();
4259 }
4260 case Intrinsic::amdgcn_frexp_exp: {
4261 // frexp_exp (fneg x) -> frexp_exp x
4262 // frexp_exp (fabs x) -> frexp_exp x
4263 // frexp_exp (fneg (fabs x)) -> frexp_exp x
4264 SDValue Src = N->getOperand(1);
4265 SDValue PeekSign = peekFPSignOps(Src);
4266 if (PeekSign == Src)
4267 return SDValue();
4268 return SDValue(DCI.DAG.UpdateNodeOperands(N, N->getOperand(0), PeekSign),
4269 0);
4270 }
4271 default:
4272 return SDValue();
4273 }
4274}
4275
4276/// Split the 64-bit value \p LHS into two 32-bit components, and perform the
4277/// binary operation \p Opc to it with the corresponding constant operands.
4279 DAGCombinerInfo &DCI, const SDLoc &SL,
4280 unsigned Opc, SDValue LHS,
4281 uint32_t ValLo, uint32_t ValHi) const {
4282 SelectionDAG &DAG = DCI.DAG;
4283 SDValue Lo, Hi;
4284 std::tie(Lo, Hi) = split64BitValue(LHS, DAG);
4285
4286 SDValue LoRHS = DAG.getConstant(ValLo, SL, MVT::i32);
4287 SDValue HiRHS = DAG.getConstant(ValHi, SL, MVT::i32);
4288
4289 SDValue LoAnd = DAG.getNode(Opc, SL, MVT::i32, Lo, LoRHS);
4290 SDValue HiAnd = DAG.getNode(Opc, SL, MVT::i32, Hi, HiRHS);
4291
4292 // Re-visit the ands. It's possible we eliminated one of them and it could
4293 // simplify the vector.
4294 DCI.AddToWorklist(Lo.getNode());
4295 DCI.AddToWorklist(Hi.getNode());
4296
4297 SDValue Vec = DAG.getBuildVector(MVT::v2i32, SL, {LoAnd, HiAnd});
4298 return DAG.getNode(ISD::BITCAST, SL, MVT::i64, Vec);
4299}
4300
4302 DAGCombinerInfo &DCI) const {
4303 EVT VT = N->getValueType(0);
4304 SDValue LHS = N->getOperand(0);
4305 SDValue RHS = N->getOperand(1);
4307 SDLoc SL(N);
4308 SelectionDAG &DAG = DCI.DAG;
4309
4310 unsigned RHSVal;
4311 if (CRHS) {
4312 RHSVal = CRHS->getZExtValue();
4313 if (!RHSVal)
4314 return LHS;
4315
4316 switch (LHS->getOpcode()) {
4317 default:
4318 break;
4319 case ISD::ZERO_EXTEND:
4320 case ISD::SIGN_EXTEND:
4321 case ISD::ANY_EXTEND: {
4322 SDValue X = LHS->getOperand(0);
4323
4324 if (VT == MVT::i32 && RHSVal == 16 && X.getValueType() == MVT::i16 &&
4325 isOperationLegal(ISD::BUILD_VECTOR, MVT::v2i16)) {
4326 // Prefer build_vector as the canonical form if packed types are legal.
4327 // (shl ([asz]ext i16:x), 16 -> build_vector 0, x
4328 SDValue Vec = DAG.getBuildVector(
4329 MVT::v2i16, SL,
4330 {DAG.getConstant(0, SL, MVT::i16), LHS->getOperand(0)});
4331 return DAG.getNode(ISD::BITCAST, SL, MVT::i32, Vec);
4332 }
4333
4334 // shl (ext x) => zext (shl x), if shift does not overflow int
4335 if (VT != MVT::i64)
4336 break;
4338 unsigned LZ = Known.countMinLeadingZeros();
4339 if (LZ < RHSVal)
4340 break;
4341 EVT XVT = X.getValueType();
4342 SDValue Shl = DAG.getNode(ISD::SHL, SL, XVT, X, SDValue(CRHS, 0));
4343 return DAG.getZExtOrTrunc(Shl, SL, VT);
4344 }
4345 }
4346 }
4347
4348 if (VT.getScalarType() != MVT::i64)
4349 return SDValue();
4350
4351 // On some subtargets, 64-bit shift is a quarter rate instruction. In the
4352 // common case, splitting this into a move and a 32-bit shift is faster and
4353 // the same code size.
4354 KnownBits Known = DAG.computeKnownBits(RHS);
4355
4356 EVT ElementType = VT.getScalarType();
4357 EVT TargetScalarType = ElementType.getHalfSizedIntegerVT(*DAG.getContext());
4358 EVT TargetType = VT.changeElementType(*DAG.getContext(), TargetScalarType);
4359
4360 if (Known.getMinValue().getZExtValue() < TargetScalarType.getSizeInBits())
4361 return SDValue();
4362 SDValue ShiftAmt;
4363
4364 if (CRHS) {
4365 ShiftAmt = DAG.getConstant(RHSVal - TargetScalarType.getSizeInBits(), SL,
4366 TargetType);
4367 } else {
4368 SDValue TruncShiftAmt = DAG.getNode(ISD::TRUNCATE, SL, TargetType, RHS);
4369 const SDValue ShiftMask =
4370 DAG.getConstant(TargetScalarType.getSizeInBits() - 1, SL, TargetType);
4371 // This AND instruction will clamp out of bounds shift values.
4372 // It will also be removed during later instruction selection.
4373 ShiftAmt = DAG.getNode(ISD::AND, SL, TargetType, TruncShiftAmt, ShiftMask);
4374 }
4375
4376 SDValue Lo = DAG.getNode(ISD::TRUNCATE, SL, TargetType, LHS);
4377 SDValue NewShift =
4378 DAG.getNode(ISD::SHL, SL, TargetType, Lo, ShiftAmt, N->getFlags());
4379
4380 const SDValue Zero = DAG.getConstant(0, SL, TargetScalarType);
4381 SDValue Vec;
4382
4383 if (VT.isVector()) {
4384 EVT ConcatType = TargetType.getDoubleNumVectorElementsVT(*DAG.getContext());
4385 unsigned NElts = TargetType.getVectorNumElements();
4387 SmallVector<SDValue, 16> HiAndLoOps(NElts * 2, Zero);
4388
4389 DAG.ExtractVectorElements(NewShift, HiOps, 0, NElts);
4390 for (unsigned I = 0; I != NElts; ++I)
4391 HiAndLoOps[2 * I + 1] = HiOps[I];
4392 Vec = DAG.getNode(ISD::BUILD_VECTOR, SL, ConcatType, HiAndLoOps);
4393 } else {
4394 EVT ConcatType = EVT::getVectorVT(*DAG.getContext(), TargetType, 2);
4395 Vec = DAG.getBuildVector(ConcatType, SL, {Zero, NewShift});
4396 }
4397 return DAG.getNode(ISD::BITCAST, SL, VT, Vec);
4398}
4399
4401 DAGCombinerInfo &DCI) const {
4402 SDValue RHS = N->getOperand(1);
4404 EVT VT = N->getValueType(0);
4405 SDValue LHS = N->getOperand(0);
4406 SelectionDAG &DAG = DCI.DAG;
4407 SDLoc SL(N);
4408
4409 if (VT.getScalarType() != MVT::i64)
4410 return SDValue();
4411
4412 // For C >= 32
4413 // i64 (sra x, C) -> (build_pair (sra hi_32(x), C - 32), sra hi_32(x), 31))
4414
4415 // On some subtargets, 64-bit shift is a quarter rate instruction. In the
4416 // common case, splitting this into a move and a 32-bit shift is faster and
4417 // the same code size.
4418 KnownBits Known = DAG.computeKnownBits(RHS);
4419
4420 EVT ElementType = VT.getScalarType();
4421 EVT TargetScalarType = ElementType.getHalfSizedIntegerVT(*DAG.getContext());
4422 EVT TargetType = VT.changeElementType(*DAG.getContext(), TargetScalarType);
4423
4424 if (Known.getMinValue().getZExtValue() < TargetScalarType.getSizeInBits())
4425 return SDValue();
4426
4427 SDValue ShiftFullAmt =
4428 DAG.getConstant(TargetScalarType.getSizeInBits() - 1, SL, TargetType);
4429 SDValue ShiftAmt;
4430 if (CRHS) {
4431 unsigned RHSVal = CRHS->getZExtValue();
4432 ShiftAmt = DAG.getConstant(RHSVal - TargetScalarType.getSizeInBits(), SL,
4433 TargetType);
4434 } else if (Known.getMinValue().getZExtValue() ==
4435 (ElementType.getSizeInBits() - 1)) {
4436 ShiftAmt = ShiftFullAmt;
4437 } else {
4438 SDValue TruncShiftAmt = DAG.getNode(ISD::TRUNCATE, SL, TargetType, RHS);
4439 const SDValue ShiftMask =
4440 DAG.getConstant(TargetScalarType.getSizeInBits() - 1, SL, TargetType);
4441 // This AND instruction will clamp out of bounds shift values.
4442 // It will also be removed during later instruction selection.
4443 ShiftAmt = DAG.getNode(ISD::AND, SL, TargetType, TruncShiftAmt, ShiftMask);
4444 }
4445
4446 EVT ConcatType;
4447 SDValue Hi;
4448 SDLoc LHSSL(LHS);
4449 // Bitcast LHS into ConcatType so hi-half of source can be extracted into Hi
4450 if (VT.isVector()) {
4451 unsigned NElts = TargetType.getVectorNumElements();
4452 ConcatType = TargetType.getDoubleNumVectorElementsVT(*DAG.getContext());
4453 SDValue SplitLHS = DAG.getNode(ISD::BITCAST, LHSSL, ConcatType, LHS);
4454 SmallVector<SDValue, 8> HiOps(NElts);
4455 SmallVector<SDValue, 16> HiAndLoOps;
4456
4457 DAG.ExtractVectorElements(SplitLHS, HiAndLoOps, 0, NElts * 2);
4458 for (unsigned I = 0; I != NElts; ++I) {
4459 HiOps[I] = HiAndLoOps[2 * I + 1];
4460 }
4461 Hi = DAG.getNode(ISD::BUILD_VECTOR, LHSSL, TargetType, HiOps);
4462 } else {
4463 const SDValue One = DAG.getConstant(1, LHSSL, TargetScalarType);
4464 ConcatType = EVT::getVectorVT(*DAG.getContext(), TargetType, 2);
4465 SDValue SplitLHS = DAG.getNode(ISD::BITCAST, LHSSL, ConcatType, LHS);
4466 Hi = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, LHSSL, TargetType, SplitLHS, One);
4467 }
4468
4469 KnownBits KnownLHS = DAG.computeKnownBits(LHS);
4470 SDValue NewShift, HiShift;
4471 if (KnownLHS.isNegative()) {
4472 HiShift = DAG.getAllOnesConstant(SL, TargetType);
4473 NewShift =
4474 DAG.getNode(ISD::SRA, SL, TargetType, Hi, ShiftAmt, N->getFlags());
4475 } else if (CRHS &&
4476 CRHS->getZExtValue() == (ElementType.getSizeInBits() - 1)) {
4477 NewShift = HiShift =
4478 DAG.getNode(ISD::SRA, SL, TargetType, Hi, ShiftAmt, N->getFlags());
4479 } else {
4480 Hi = DAG.getFreeze(Hi);
4481 HiShift = DAG.getNode(ISD::SRA, SL, TargetType, Hi, ShiftFullAmt);
4482 NewShift =
4483 DAG.getNode(ISD::SRA, SL, TargetType, Hi, ShiftAmt, N->getFlags());
4484 }
4485
4486 SDValue Vec;
4487 if (VT.isVector()) {
4488 unsigned NElts = TargetType.getVectorNumElements();
4491 SmallVector<SDValue, 16> HiAndLoOps(NElts * 2);
4492
4493 DAG.ExtractVectorElements(HiShift, HiOps, 0, NElts);
4494 DAG.ExtractVectorElements(NewShift, LoOps, 0, NElts);
4495 for (unsigned I = 0; I != NElts; ++I) {
4496 HiAndLoOps[2 * I + 1] = HiOps[I];
4497 HiAndLoOps[2 * I] = LoOps[I];
4498 }
4499 Vec = DAG.getNode(ISD::BUILD_VECTOR, SL, ConcatType, HiAndLoOps);
4500 } else {
4501 Vec = DAG.getBuildVector(ConcatType, SL, {NewShift, HiShift});
4502 }
4503 return DAG.getNode(ISD::BITCAST, SL, VT, Vec);
4504}
4505
4507 DAGCombinerInfo &DCI) const {
4508 SDValue RHS = N->getOperand(1);
4510 EVT VT = N->getValueType(0);
4511 SDValue LHS = N->getOperand(0);
4512 SelectionDAG &DAG = DCI.DAG;
4513 SDLoc SL(N);
4514 unsigned RHSVal;
4515
4516 if (CRHS) {
4517 RHSVal = CRHS->getZExtValue();
4518
4519 // fold (srl (and x, c1 << c2), c2) -> (and (srl(x, c2), c1)
4520 // this improves the ability to match BFE patterns in isel.
4521 if (LHS.getOpcode() == ISD::AND) {
4522 if (auto *Mask = dyn_cast<ConstantSDNode>(LHS.getOperand(1))) {
4523 unsigned MaskIdx, MaskLen;
4524 if (Mask->getAPIntValue().isShiftedMask(MaskIdx, MaskLen) &&
4525 MaskIdx == RHSVal) {
4526 return DAG.getNode(ISD::AND, SL, VT,
4527 DAG.getNode(ISD::SRL, SL, VT, LHS.getOperand(0),
4528 N->getOperand(1)),
4529 DAG.getNode(ISD::SRL, SL, VT, LHS.getOperand(1),
4530 N->getOperand(1)));
4531 }
4532 }
4533 }
4534 }
4535
4536 if (VT.getScalarType() != MVT::i64)
4537 return SDValue();
4538
4539 // for C >= 32
4540 // i64 (srl x, C) -> (build_pair (srl hi_32(x), C - 32), 0)
4541
4542 // On some subtargets, 64-bit shift is a quarter rate instruction. In the
4543 // common case, splitting this into a move and a 32-bit shift is faster and
4544 // the same code size.
4545 KnownBits Known = DAG.computeKnownBits(RHS);
4546
4547 EVT ElementType = VT.getScalarType();
4548 EVT TargetScalarType = ElementType.getHalfSizedIntegerVT(*DAG.getContext());
4549 EVT TargetType = VT.changeElementType(*DAG.getContext(), TargetScalarType);
4550
4551 if (Known.getMinValue().getZExtValue() < TargetScalarType.getSizeInBits())
4552 return SDValue();
4553
4554 SDValue ShiftAmt;
4555 if (CRHS) {
4556 ShiftAmt = DAG.getConstant(RHSVal - TargetScalarType.getSizeInBits(), SL,
4557 TargetType);
4558 } else {
4559 SDValue TruncShiftAmt = DAG.getNode(ISD::TRUNCATE, SL, TargetType, RHS);
4560 const SDValue ShiftMask =
4561 DAG.getConstant(TargetScalarType.getSizeInBits() - 1, SL, TargetType);
4562 // This AND instruction will clamp out of bounds shift values.
4563 // It will also be removed during later instruction selection.
4564 ShiftAmt = DAG.getNode(ISD::AND, SL, TargetType, TruncShiftAmt, ShiftMask);
4565 }
4566
4567 const SDValue Zero = DAG.getConstant(0, SL, TargetScalarType);
4568 EVT ConcatType;
4569 SDValue Hi;
4570 SDLoc LHSSL(LHS);
4571 // Bitcast LHS into ConcatType so hi-half of source can be extracted into Hi
4572 if (VT.isVector()) {
4573 unsigned NElts = TargetType.getVectorNumElements();
4574 ConcatType = TargetType.getDoubleNumVectorElementsVT(*DAG.getContext());
4575 SDValue SplitLHS = DAG.getNode(ISD::BITCAST, LHSSL, ConcatType, LHS);
4576 SmallVector<SDValue, 8> HiOps(NElts);
4577 SmallVector<SDValue, 16> HiAndLoOps;
4578
4579 DAG.ExtractVectorElements(SplitLHS, HiAndLoOps, /*Start=*/0, NElts * 2);
4580 for (unsigned I = 0; I != NElts; ++I)
4581 HiOps[I] = HiAndLoOps[2 * I + 1];
4582 Hi = DAG.getNode(ISD::BUILD_VECTOR, LHSSL, TargetType, HiOps);
4583 } else {
4584 const SDValue One = DAG.getConstant(1, LHSSL, TargetScalarType);
4585 ConcatType = EVT::getVectorVT(*DAG.getContext(), TargetType, 2);
4586 SDValue SplitLHS = DAG.getNode(ISD::BITCAST, LHSSL, ConcatType, LHS);
4587 Hi = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, LHSSL, TargetType, SplitLHS, One);
4588 }
4589
4590 SDValue NewShift =
4591 DAG.getNode(ISD::SRL, SL, TargetType, Hi, ShiftAmt, N->getFlags());
4592
4593 SDValue Vec;
4594 if (VT.isVector()) {
4595 unsigned NElts = TargetType.getVectorNumElements();
4597 SmallVector<SDValue, 16> HiAndLoOps(NElts * 2, Zero);
4598
4599 DAG.ExtractVectorElements(NewShift, LoOps, 0, NElts);
4600 for (unsigned I = 0; I != NElts; ++I)
4601 HiAndLoOps[2 * I] = LoOps[I];
4602 Vec = DAG.getNode(ISD::BUILD_VECTOR, SL, ConcatType, HiAndLoOps);
4603 } else {
4604 Vec = DAG.getBuildVector(ConcatType, SL, {NewShift, Zero});
4605 }
4606 return DAG.getNode(ISD::BITCAST, SL, VT, Vec);
4607}
4608
4610 SDNode *N, DAGCombinerInfo &DCI) const {
4611 SDLoc SL(N);
4612 SelectionDAG &DAG = DCI.DAG;
4613 EVT VT = N->getValueType(0);
4614 SDValue Src = N->getOperand(0);
4615
4616 // vt1 (truncate (bitcast (build_vector vt0:x, ...))) -> vt1 (bitcast vt0:x)
4617 if (Src.getOpcode() == ISD::BITCAST && !VT.isVector()) {
4618 SDValue Vec = Src.getOperand(0);
4619 if (Vec.getOpcode() == ISD::BUILD_VECTOR) {
4620 SDValue Elt0 = Vec.getOperand(0);
4621 EVT EltVT = Elt0.getValueType();
4622 if (VT.getFixedSizeInBits() <= EltVT.getFixedSizeInBits()) {
4623 if (EltVT.isFloatingPoint()) {
4624 Elt0 = DAG.getNode(ISD::BITCAST, SL,
4625 EltVT.changeTypeToInteger(), Elt0);
4626 }
4627
4628 return DAG.getNode(ISD::TRUNCATE, SL, VT, Elt0);
4629 }
4630 }
4631 }
4632
4633 // Equivalent of above for accessing the high element of a vector as an
4634 // integer operation.
4635 // trunc (srl (bitcast (build_vector x, y))), 16 -> trunc (bitcast y)
4636 if (Src.getOpcode() == ISD::SRL && !VT.isVector()) {
4637 if (auto *K = isConstOrConstSplat(Src.getOperand(1))) {
4638 SDValue BV = stripBitcast(Src.getOperand(0));
4639 if (BV.getOpcode() == ISD::BUILD_VECTOR) {
4640 EVT SrcEltVT = BV.getOperand(0).getValueType();
4641 unsigned SrcEltSize = SrcEltVT.getSizeInBits();
4642 unsigned BitIndex = K->getZExtValue();
4643 unsigned PartIndex = BitIndex / SrcEltSize;
4644
4645 if (PartIndex * SrcEltSize == BitIndex &&
4646 PartIndex < BV.getNumOperands()) {
4647 if (SrcEltVT.getSizeInBits() == VT.getSizeInBits()) {
4648 SDValue SrcElt =
4649 DAG.getNode(ISD::BITCAST, SL, SrcEltVT.changeTypeToInteger(),
4650 BV.getOperand(PartIndex));
4651 return DAG.getNode(ISD::TRUNCATE, SL, VT, SrcElt);
4652 }
4653 }
4654 }
4655 }
4656 }
4657
4658 // Partially shrink 64-bit shifts to 32-bit if reduced to 16-bit.
4659 //
4660 // i16 (trunc (srl i64:x, K)), K <= 16 ->
4661 // i16 (trunc (srl (i32 (trunc x), K)))
4662 if (VT.getScalarSizeInBits() < 32) {
4663 EVT SrcVT = Src.getValueType();
4664 if (SrcVT.getScalarSizeInBits() > 32 &&
4665 (Src.getOpcode() == ISD::SRL ||
4666 Src.getOpcode() == ISD::SRA ||
4667 Src.getOpcode() == ISD::SHL)) {
4668 SDValue Amt = Src.getOperand(1);
4669 KnownBits Known = DAG.computeKnownBits(Amt);
4670
4671 // - For left shifts, do the transform as long as the shift
4672 // amount is still legal for i32, so when ShiftAmt < 32 (<= 31)
4673 // - For right shift, do it if ShiftAmt <= (32 - Size) to avoid
4674 // losing information stored in the high bits when truncating.
4675 const unsigned MaxCstSize =
4676 (Src.getOpcode() == ISD::SHL) ? 31 : (32 - VT.getScalarSizeInBits());
4677 if (Known.getMaxValue().ule(MaxCstSize)) {
4678 EVT MidVT = VT.isVector() ?
4679 EVT::getVectorVT(*DAG.getContext(), MVT::i32,
4680 VT.getVectorNumElements()) : MVT::i32;
4681
4682 EVT NewShiftVT = getShiftAmountTy(MidVT, DAG.getDataLayout());
4683 SDValue Trunc = DAG.getNode(ISD::TRUNCATE, SL, MidVT,
4684 Src.getOperand(0));
4685 DCI.AddToWorklist(Trunc.getNode());
4686
4687 if (Amt.getValueType() != NewShiftVT) {
4688 Amt = DAG.getZExtOrTrunc(Amt, SL, NewShiftVT);
4689 DCI.AddToWorklist(Amt.getNode());
4690 }
4691
4692 SDValue ShrunkShift = DAG.getNode(Src.getOpcode(), SL, MidVT,
4693 Trunc, Amt);
4694 return DAG.getNode(ISD::TRUNCATE, SL, VT, ShrunkShift);
4695 }
4696 }
4697 }
4698
4699 return SDValue();
4700}
4701
4702// We need to specifically handle i64 mul here to avoid unnecessary conversion
4703// instructions. If we only match on the legalized i64 mul expansion,
4704// SimplifyDemandedBits will be unable to remove them because there will be
4705// multiple uses due to the separate mul + mulh[su].
4706static SDValue getMul24(SelectionDAG &DAG, const SDLoc &SL,
4707 SDValue N0, SDValue N1, unsigned Size, bool Signed) {
4708 if (Size <= 32) {
4709 unsigned MulOpc = Signed ? AMDGPUISD::MUL_I24 : AMDGPUISD::MUL_U24;
4710 return DAG.getNode(MulOpc, SL, MVT::i32, N0, N1);
4711 }
4712
4713 unsigned MulLoOpc = Signed ? AMDGPUISD::MUL_I24 : AMDGPUISD::MUL_U24;
4714 unsigned MulHiOpc = Signed ? AMDGPUISD::MULHI_I24 : AMDGPUISD::MULHI_U24;
4715
4716 SDValue MulLo = DAG.getNode(MulLoOpc, SL, MVT::i32, N0, N1);
4717 SDValue MulHi = DAG.getNode(MulHiOpc, SL, MVT::i32, N0, N1);
4718
4719 return DAG.getNode(ISD::BUILD_PAIR, SL, MVT::i64, MulLo, MulHi);
4720}
4721
4722/// If \p V is an add of a constant 1, returns the other operand. Otherwise
4723/// return SDValue().
4724static SDValue getAddOneOp(const SDNode *V) {
4725 if (V->getOpcode() != ISD::ADD)
4726 return SDValue();
4727
4728 return isOneConstant(V->getOperand(1)) ? V->getOperand(0) : SDValue();
4729}
4730
4732 DAGCombinerInfo &DCI) const {
4733 assert(N->getOpcode() == ISD::MUL);
4734 EVT VT = N->getValueType(0);
4735
4736 // Don't generate 24-bit multiplies on values that are in SGPRs, since
4737 // we only have a 32-bit scalar multiply (avoid values being moved to VGPRs
4738 // unnecessarily). isDivergent() is used as an approximation of whether the
4739 // value is in an SGPR.
4740 if (!N->isDivergent())
4741 return SDValue();
4742
4743 unsigned Size = VT.getSizeInBits();
4744 if (VT.isVector() || Size > 64)
4745 return SDValue();
4746
4747 SelectionDAG &DAG = DCI.DAG;
4748 SDLoc DL(N);
4749
4750 SDValue N0 = N->getOperand(0);
4751 SDValue N1 = N->getOperand(1);
4752
4753 // Undo InstCombine canonicalize X * (Y + 1) -> X * Y + X to enable mad
4754 // matching.
4755
4756 // mul x, (add y, 1) -> add (mul x, y), x
4757 auto IsFoldableAdd = [](SDValue V) -> SDValue {
4758 SDValue AddOp = getAddOneOp(V.getNode());
4759 if (!AddOp)
4760 return SDValue();
4761
4762 if (V.hasOneUse() || all_of(V->users(), [](const SDNode *U) -> bool {
4763 return U->getOpcode() == ISD::MUL;
4764 }))
4765 return AddOp;
4766
4767 return SDValue();
4768 };
4769
4770 // FIXME: The selection pattern is not properly checking for commuted
4771 // operands, so we have to place the mul in the LHS
4772 if (SDValue MulOper = IsFoldableAdd(N0)) {
4773 SDValue MulVal = DAG.getNode(N->getOpcode(), DL, VT, N1, MulOper);
4774 return DAG.getNode(ISD::ADD, DL, VT, MulVal, N1);
4775 }
4776
4777 if (SDValue MulOper = IsFoldableAdd(N1)) {
4778 SDValue MulVal = DAG.getNode(N->getOpcode(), DL, VT, N0, MulOper);
4779 return DAG.getNode(ISD::ADD, DL, VT, MulVal, N0);
4780 }
4781
4782 // There are i16 integer mul/mad.
4783 if (isTypeLegal(MVT::i16) && VT.getScalarType().bitsLE(MVT::i16))
4784 return SDValue();
4785
4786 // SimplifyDemandedBits has the annoying habit of turning useful zero_extends
4787 // in the source into any_extends if the result of the mul is truncated. Since
4788 // we can assume the high bits are whatever we want, use the underlying value
4789 // to avoid the unknown high bits from interfering.
4790 if (N0.getOpcode() == ISD::ANY_EXTEND)
4791 N0 = N0.getOperand(0);
4792
4793 if (N1.getOpcode() == ISD::ANY_EXTEND)
4794 N1 = N1.getOperand(0);
4795
4796 SDValue Mul;
4797
4798 if (Subtarget->hasMulU24() && isU24(N0, DAG) && isU24(N1, DAG)) {
4799 N0 = DAG.getZExtOrTrunc(N0, DL, MVT::i32);
4800 N1 = DAG.getZExtOrTrunc(N1, DL, MVT::i32);
4801 Mul = getMul24(DAG, DL, N0, N1, Size, false);
4802 } else if (Subtarget->hasMulI24() && isI24(N0, DAG) && isI24(N1, DAG)) {
4803 N0 = DAG.getSExtOrTrunc(N0, DL, MVT::i32);
4804 N1 = DAG.getSExtOrTrunc(N1, DL, MVT::i32);
4805 Mul = getMul24(DAG, DL, N0, N1, Size, true);
4806 } else {
4807 return SDValue();
4808 }
4809
4810 // We need to use sext even for MUL_U24, because MUL_U24 is used
4811 // for signed multiply of 8 and 16-bit types.
4812 return DAG.getSExtOrTrunc(Mul, DL, VT);
4813}
4814
4815SDValue
4817 DAGCombinerInfo &DCI) const {
4818 if (N->getValueType(0) != MVT::i32)
4819 return SDValue();
4820
4821 SelectionDAG &DAG = DCI.DAG;
4822 SDLoc DL(N);
4823
4824 bool Signed = N->getOpcode() == ISD::SMUL_LOHI;
4825 SDValue N0 = N->getOperand(0);
4826 SDValue N1 = N->getOperand(1);
4827
4828 // SimplifyDemandedBits has the annoying habit of turning useful zero_extends
4829 // in the source into any_extends if the result of the mul is truncated. Since
4830 // we can assume the high bits are whatever we want, use the underlying value
4831 // to avoid the unknown high bits from interfering.
4832 if (N0.getOpcode() == ISD::ANY_EXTEND)
4833 N0 = N0.getOperand(0);
4834 if (N1.getOpcode() == ISD::ANY_EXTEND)
4835 N1 = N1.getOperand(0);
4836
4837 // Try to use two fast 24-bit multiplies (one for each half of the result)
4838 // instead of one slow extending multiply.
4839 unsigned LoOpcode = 0;
4840 unsigned HiOpcode = 0;
4841 if (Signed) {
4842 if (Subtarget->hasMulI24() && isI24(N0, DAG) && isI24(N1, DAG)) {
4843 N0 = DAG.getSExtOrTrunc(N0, DL, MVT::i32);
4844 N1 = DAG.getSExtOrTrunc(N1, DL, MVT::i32);
4845 LoOpcode = AMDGPUISD::MUL_I24;
4846 HiOpcode = AMDGPUISD::MULHI_I24;
4847 }
4848 } else {
4849 if (Subtarget->hasMulU24() && isU24(N0, DAG) && isU24(N1, DAG)) {
4850 N0 = DAG.getZExtOrTrunc(N0, DL, MVT::i32);
4851 N1 = DAG.getZExtOrTrunc(N1, DL, MVT::i32);
4852 LoOpcode = AMDGPUISD::MUL_U24;
4853 HiOpcode = AMDGPUISD::MULHI_U24;
4854 }
4855 }
4856 if (!LoOpcode)
4857 return SDValue();
4858
4859 SDValue Lo = DAG.getNode(LoOpcode, DL, MVT::i32, N0, N1);
4860 SDValue Hi = DAG.getNode(HiOpcode, DL, MVT::i32, N0, N1);
4861 DCI.CombineTo(N, Lo, Hi);
4862 return SDValue(N, 0);
4863}
4864
4866 DAGCombinerInfo &DCI) const {
4867 EVT VT = N->getValueType(0);
4868
4869 if (!Subtarget->hasMulI24() || VT.isVector())
4870 return SDValue();
4871
4872 // Don't generate 24-bit multiplies on values that are in SGPRs, since
4873 // we only have a 32-bit scalar multiply (avoid values being moved to VGPRs
4874 // unnecessarily). isDivergent() is used as an approximation of whether the
4875 // value is in an SGPR.
4876 // This doesn't apply if no s_mul_hi is available (since we'll end up with a
4877 // valu op anyway)
4878 if (Subtarget->hasSMulHi() && !N->isDivergent())
4879 return SDValue();
4880
4881 SelectionDAG &DAG = DCI.DAG;
4882 SDLoc DL(N);
4883
4884 SDValue N0 = N->getOperand(0);
4885 SDValue N1 = N->getOperand(1);
4886
4887 if (!isI24(N0, DAG) || !isI24(N1, DAG))
4888 return SDValue();
4889
4890 N0 = DAG.getSExtOrTrunc(N0, DL, MVT::i32);
4891 N1 = DAG.getSExtOrTrunc(N1, DL, MVT::i32);
4892
4893 SDValue Mulhi = DAG.getNode(AMDGPUISD::MULHI_I24, DL, MVT::i32, N0, N1);
4894 DCI.AddToWorklist(Mulhi.getNode());
4895 return DAG.getSExtOrTrunc(Mulhi, DL, VT);
4896}
4897
4899 DAGCombinerInfo &DCI) const {
4900 EVT VT = N->getValueType(0);
4901
4902 if (VT.isVector() || VT.getSizeInBits() > 32 || !Subtarget->hasMulU24())
4903 return SDValue();
4904
4905 // Don't generate 24-bit multiplies on values that are in SGPRs, since
4906 // we only have a 32-bit scalar multiply (avoid values being moved to VGPRs
4907 // unnecessarily). isDivergent() is used as an approximation of whether the
4908 // value is in an SGPR.
4909 // This doesn't apply if no s_mul_hi is available (since we'll end up with a
4910 // valu op anyway)
4911 if (!N->isDivergent() && Subtarget->hasSMulHi())
4912 return SDValue();
4913
4914 SelectionDAG &DAG = DCI.DAG;
4915 SDLoc DL(N);
4916
4917 SDValue N0 = N->getOperand(0);
4918 SDValue N1 = N->getOperand(1);
4919
4920 if (!isU24(N0, DAG) || !isU24(N1, DAG))
4921 return SDValue();
4922
4923 N0 = DAG.getZExtOrTrunc(N0, DL, MVT::i32);
4924 N1 = DAG.getZExtOrTrunc(N1, DL, MVT::i32);
4925
4926 SDValue Mulhi = DAG.getNode(AMDGPUISD::MULHI_U24, DL, MVT::i32, N0, N1);
4927 DCI.AddToWorklist(Mulhi.getNode());
4928 return DAG.getZExtOrTrunc(Mulhi, DL, VT);
4929}
4930
4931SDValue AMDGPUTargetLowering::getFFBX_U32(SelectionDAG &DAG,
4932 SDValue Op,
4933 const SDLoc &DL,
4934 unsigned Opc) const {
4935 EVT VT = Op.getValueType();
4936 if (VT.bitsGT(MVT::i32))
4937 return SDValue();
4938
4939 if (VT != MVT::i32)
4940 Op = DAG.getNode(ISD::ZERO_EXTEND, DL, MVT::i32, Op);
4941
4942 SDValue FFBX = DAG.getNode(Opc, DL, MVT::i32, Op);
4943 if (VT != MVT::i32)
4944 FFBX = DAG.getNode(ISD::TRUNCATE, DL, VT, FFBX);
4945
4946 return FFBX;
4947}
4948
4949// The native instructions return -1 on 0 input. Optimize out a select that
4950// produces -1 on 0.
4951//
4952// TODO: If zero is not undef, we could also do this if the output is compared
4953// against the bitwidth.
4954//
4955// TODO: Should probably combine against FFBH_U32 instead of ctlz directly.
4957 SDValue LHS, SDValue RHS,
4958 DAGCombinerInfo &DCI) const {
4959 if (!isNullConstant(Cond.getOperand(1)))
4960 return SDValue();
4961
4962 SelectionDAG &DAG = DCI.DAG;
4963 ISD::CondCode CCOpcode = cast<CondCodeSDNode>(Cond.getOperand(2))->get();
4964 SDValue CmpLHS = Cond.getOperand(0);
4965
4966 // select (setcc x, 0, eq), -1, (ctlz_zero_poison x) -> ffbh_u32 x
4967 // select (setcc x, 0, eq), -1, (cttz_zero_poison x) -> ffbl_u32 x
4968 if (CCOpcode == ISD::SETEQ &&
4969 (isCtlzOpc(RHS.getOpcode()) || isCttzOpc(RHS.getOpcode())) &&
4970 RHS.getOperand(0) == CmpLHS && isAllOnesConstant(LHS)) {
4971 unsigned Opc =
4972 isCttzOpc(RHS.getOpcode()) ? AMDGPUISD::FFBL_B32 : AMDGPUISD::FFBH_U32;
4973 return getFFBX_U32(DAG, CmpLHS, SL, Opc);
4974 }
4975
4976 // select (setcc x, 0, ne), (ctlz_zero_poison x), -1 -> ffbh_u32 x
4977 // select (setcc x, 0, ne), (cttz_zero_poison x), -1 -> ffbl_u32 x
4978 if (CCOpcode == ISD::SETNE &&
4979 (isCtlzOpc(LHS.getOpcode()) || isCttzOpc(LHS.getOpcode())) &&
4980 LHS.getOperand(0) == CmpLHS && isAllOnesConstant(RHS)) {
4981 unsigned Opc =
4982 isCttzOpc(LHS.getOpcode()) ? AMDGPUISD::FFBL_B32 : AMDGPUISD::FFBH_U32;
4983
4984 return getFFBX_U32(DAG, CmpLHS, SL, Opc);
4985 }
4986
4987 return SDValue();
4988}
4989
4991 unsigned Op,
4992 const SDLoc &SL,
4993 SDValue Cond,
4994 SDValue N1,
4995 SDValue N2) {
4996 SelectionDAG &DAG = DCI.DAG;
4997 EVT VT = N1.getValueType();
4998
4999 SDValue NewSelect = DAG.getNode(ISD::SELECT, SL, VT, Cond,
5000 N1.getOperand(0), N2.getOperand(0));
5001 DCI.AddToWorklist(NewSelect.getNode());
5002 return DAG.getNode(Op, SL, VT, NewSelect);
5003}
5004
5005// Pull a free FP operation out of a select so it may fold into uses.
5006//
5007// select c, (fneg x), (fneg y) -> fneg (select c, x, y)
5008// select c, (fneg x), k -> fneg (select c, x, (fneg k))
5009//
5010// select c, (fabs x), (fabs y) -> fabs (select c, x, y)
5011// select c, (fabs x), +k -> fabs (select c, x, k)
5012SDValue
5014 SDValue N) const {
5015 SelectionDAG &DAG = DCI.DAG;
5016 SDValue Cond = N.getOperand(0);
5017 SDValue LHS = N.getOperand(1);
5018 SDValue RHS = N.getOperand(2);
5019
5020 EVT VT = N.getValueType();
5021 if ((LHS.getOpcode() == ISD::FABS && RHS.getOpcode() == ISD::FABS) ||
5022 (LHS.getOpcode() == ISD::FNEG && RHS.getOpcode() == ISD::FNEG)) {
5024 return SDValue();
5025
5026 return distributeOpThroughSelect(DCI, LHS.getOpcode(),
5027 SDLoc(N), Cond, LHS, RHS);
5028 }
5029
5030 bool Inv = false;
5031 if (RHS.getOpcode() == ISD::FABS || RHS.getOpcode() == ISD::FNEG) {
5032 std::swap(LHS, RHS);
5033 Inv = true;
5034 }
5035
5036 // TODO: Support vector constants.
5038 if ((LHS.getOpcode() == ISD::FNEG || LHS.getOpcode() == ISD::FABS) && CRHS &&
5039 !selectSupportsSourceMods(N.getNode())) {
5040 SDLoc SL(N);
5041 // If one side is an fneg/fabs and the other is a constant, we can push the
5042 // fneg/fabs down. If it's an fabs, the constant needs to be non-negative.
5043 SDValue NewLHS = LHS.getOperand(0);
5044 SDValue NewRHS = RHS;
5045
5046 // Careful: if the neg can be folded up, don't try to pull it back down.
5047 bool ShouldFoldNeg = true;
5048
5049 if (NewLHS.hasOneUse()) {
5050 unsigned Opc = NewLHS.getOpcode();
5051 if (LHS.getOpcode() == ISD::FNEG && fnegFoldsIntoOp(NewLHS.getNode()))
5052 ShouldFoldNeg = false;
5053 if (LHS.getOpcode() == ISD::FABS && Opc == ISD::FMUL)
5054 ShouldFoldNeg = false;
5055 }
5056
5057 if (ShouldFoldNeg) {
5058 if (LHS.getOpcode() == ISD::FABS && CRHS->isNegative())
5059 return SDValue();
5060
5061 // We're going to be forced to use a source modifier anyway, there's no
5062 // point to pulling the negate out unless we can get a size reduction by
5063 // negating the constant.
5064 //
5065 // TODO: Generalize to use getCheaperNegatedExpression which doesn't know
5066 // about cheaper constants.
5067 if (NewLHS.getOpcode() == ISD::FABS &&
5069 return SDValue();
5070
5072 return SDValue();
5073
5074 if (LHS.getOpcode() == ISD::FNEG)
5075 NewRHS = DAG.getNode(ISD::FNEG, SL, VT, RHS);
5076
5077 if (Inv)
5078 std::swap(NewLHS, NewRHS);
5079
5080 SDValue NewSelect = DAG.getNode(ISD::SELECT, SL, VT,
5081 Cond, NewLHS, NewRHS);
5082 DCI.AddToWorklist(NewSelect.getNode());
5083 return DAG.getNode(LHS.getOpcode(), SL, VT, NewSelect);
5084 }
5085 }
5086
5087 return SDValue();
5088}
5089
5091 DAGCombinerInfo &DCI) const {
5092 if (SDValue Folded = foldFreeOpFromSelect(DCI, SDValue(N, 0)))
5093 return Folded;
5094
5095 SDValue Cond = N->getOperand(0);
5096 if (Cond.getOpcode() != ISD::SETCC)
5097 return SDValue();
5098
5099 EVT VT = N->getValueType(0);
5100 SDValue LHS = Cond.getOperand(0);
5101 SDValue RHS = Cond.getOperand(1);
5102 SDValue CC = Cond.getOperand(2);
5103
5104 SDValue True = N->getOperand(1);
5105 SDValue False = N->getOperand(2);
5106
5107 if (Cond.hasOneUse()) { // TODO: Look for multiple select uses.
5108 SelectionDAG &DAG = DCI.DAG;
5109 if (DAG.isConstantValueOfAnyType(True) &&
5111 // Swap cmp + select pair to move constant to false input.
5112 // This will allow using VOPC cndmasks more often.
5113 // select (setcc x, y), k, x -> select (setccinv x, y), x, k
5114
5115 SDLoc SL(N);
5116 ISD::CondCode NewCC =
5117 getSetCCInverse(cast<CondCodeSDNode>(CC)->get(), LHS.getValueType());
5118
5119 SDValue NewCond = DAG.getSetCC(SL, Cond.getValueType(), LHS, RHS, NewCC);
5120 return DAG.getNode(ISD::SELECT, SL, VT, NewCond, False, True);
5121 }
5122
5123 if (VT == MVT::f32 && Subtarget->hasFminFmaxLegacy()) {
5124 SDValue MinMax = combineFMinMaxLegacy(SDLoc(N), VT, LHS, RHS, True, False,
5125 CC, N->getFlags(), DCI);
5126 // Revisit this node so we can catch min3/max3/med3 patterns.
5127 //DCI.AddToWorklist(MinMax.getNode());
5128 return MinMax;
5129 }
5130 }
5131
5132 // There's no reason to not do this if the condition has other uses.
5133 return performCtlz_CttzCombine(SDLoc(N), Cond, True, False, DCI);
5134}
5135
5136static bool isInv2Pi(const APFloat &APF) {
5137 static const APFloat KF16(APFloat::IEEEhalf(), APInt(16, 0x3118));
5138 static const APFloat KF32(APFloat::IEEEsingle(), APInt(32, 0x3e22f983));
5139 static const APFloat KF64(APFloat::IEEEdouble(), APInt(64, 0x3fc45f306dc9c882));
5140
5141 return APF.bitwiseIsEqual(KF16) ||
5142 APF.bitwiseIsEqual(KF32) ||
5143 APF.bitwiseIsEqual(KF64);
5144}
5145
5146// 0 and 1.0 / (0.5 * pi) do not have inline immmediates, so there is an
5147// additional cost to negate them.
5150 if (C->isZero())
5151 return C->isNegative() ? NegatibleCost::Cheaper : NegatibleCost::Expensive;
5152
5153 if (Subtarget->hasInv2PiInlineImm() && isInv2Pi(C->getValueAPF()))
5154 return C->isNegative() ? NegatibleCost::Cheaper : NegatibleCost::Expensive;
5155
5157}
5158
5164
5165static unsigned inverseMinMax(unsigned Opc) {
5166 switch (Opc) {
5167 case ISD::FMAXNUM:
5168 return ISD::FMINNUM;
5169 case ISD::FMINNUM:
5170 return ISD::FMAXNUM;
5171 case ISD::FMAXNUM_IEEE:
5172 return ISD::FMINNUM_IEEE;
5173 case ISD::FMINNUM_IEEE:
5174 return ISD::FMAXNUM_IEEE;
5175 case ISD::FMAXIMUM:
5176 return ISD::FMINIMUM;
5177 case ISD::FMINIMUM:
5178 return ISD::FMAXIMUM;
5179 case ISD::FMAXIMUMNUM:
5180 return ISD::FMINIMUMNUM;
5181 case ISD::FMINIMUMNUM:
5182 return ISD::FMAXIMUMNUM;
5183 case AMDGPUISD::FMAX_LEGACY:
5184 return AMDGPUISD::FMIN_LEGACY;
5185 case AMDGPUISD::FMIN_LEGACY:
5186 return AMDGPUISD::FMAX_LEGACY;
5187 default:
5188 llvm_unreachable("invalid min/max opcode");
5189 }
5190}
5191
5192/// \return true if it's profitable to try to push an fneg into its source
5193/// instruction.
5195 // If the input has multiple uses and we can either fold the negate down, or
5196 // the other uses cannot, give up. This both prevents unprofitable
5197 // transformations and infinite loops: we won't repeatedly try to fold around
5198 // a negate that has no 'good' form.
5199 if (N0.hasOneUse()) {
5200 // This may be able to fold into the source, but at a code size cost. Don't
5201 // fold if the fold into the user is free.
5202 if (allUsesHaveSourceMods(N, 0))
5203 return false;
5204 } else {
5205 if (fnegFoldsIntoOp(N0.getNode()) &&
5207 return false;
5208 }
5209
5210 return true;
5211}
5212
5214 DAGCombinerInfo &DCI) const {
5215 SelectionDAG &DAG = DCI.DAG;
5216 SDValue N0 = N->getOperand(0);
5217 EVT VT = N->getValueType(0);
5218
5219 unsigned Opc = N0.getOpcode();
5220
5221 if (!shouldFoldFNegIntoSrc(N, N0))
5222 return SDValue();
5223
5224 bool MayIgnoreSignedZeroForAllUses =
5225 N0->getFlags().hasNoSignedZeros() ||
5226 (N0.hasOneUse() && N->getFlags().hasNoSignedZeros());
5227
5228 SDLoc SL(N);
5229 switch (Opc) {
5230 case ISD::FADD: {
5231 if (!MayIgnoreSignedZeroForAllUses)
5232 return SDValue();
5233
5234 // (fneg (fadd x, y)) -> (fadd (fneg x), (fneg y))
5235 SDValue LHS = N0.getOperand(0);
5236 SDValue RHS = N0.getOperand(1);
5237
5238 if (LHS.getOpcode() != ISD::FNEG)
5239 LHS = DAG.getNode(ISD::FNEG, SL, VT, LHS);
5240 else
5241 LHS = LHS.getOperand(0);
5242
5243 if (RHS.getOpcode() != ISD::FNEG)
5244 RHS = DAG.getNode(ISD::FNEG, SL, VT, RHS);
5245 else
5246 RHS = RHS.getOperand(0);
5247
5248 SDValue Res = DAG.getNode(ISD::FADD, SL, VT, LHS, RHS, N0->getFlags());
5249 if (Res.getOpcode() != ISD::FADD)
5250 return SDValue(); // Op got folded away.
5251 if (!N0.hasOneUse())
5252 DAG.ReplaceAllUsesWith(N0, DAG.getNode(ISD::FNEG, SL, VT, Res));
5253 return Res;
5254 }
5255 case ISD::FMUL:
5256 case AMDGPUISD::FMUL_LEGACY: {
5257 // (fneg (fmul x, y)) -> (fmul x, (fneg y))
5258 // (fneg (fmul_legacy x, y)) -> (fmul_legacy x, (fneg y))
5259 SDValue LHS = N0.getOperand(0);
5260 SDValue RHS = N0.getOperand(1);
5261
5262 if (LHS.getOpcode() == ISD::FNEG)
5263 LHS = LHS.getOperand(0);
5264 else if (RHS.getOpcode() == ISD::FNEG)
5265 RHS = RHS.getOperand(0);
5266 else
5267 RHS = DAG.getNode(ISD::FNEG, SL, VT, RHS);
5268
5269 SDValue Res = DAG.getNode(Opc, SL, VT, LHS, RHS, N0->getFlags());
5270 if (Res.getOpcode() != Opc)
5271 return SDValue(); // Op got folded away.
5272 if (!N0.hasOneUse())
5273 DAG.ReplaceAllUsesWith(N0, DAG.getNode(ISD::FNEG, SL, VT, Res));
5274 return Res;
5275 }
5276 case ISD::FMA:
5277 case ISD::FMAD: {
5278 // TODO: handle llvm.amdgcn.fma.legacy
5279 if (!MayIgnoreSignedZeroForAllUses)
5280 return SDValue();
5281
5282 // (fneg (fma x, y, z)) -> (fma x, (fneg y), (fneg z))
5283 SDValue LHS = N0.getOperand(0);
5284 SDValue MHS = N0.getOperand(1);
5285 SDValue RHS = N0.getOperand(2);
5286
5287 if (LHS.getOpcode() == ISD::FNEG)
5288 LHS = LHS.getOperand(0);
5289 else if (MHS.getOpcode() == ISD::FNEG)
5290 MHS = MHS.getOperand(0);
5291 else
5292 MHS = DAG.getNode(ISD::FNEG, SL, VT, MHS);
5293
5294 if (RHS.getOpcode() != ISD::FNEG)
5295 RHS = DAG.getNode(ISD::FNEG, SL, VT, RHS);
5296 else
5297 RHS = RHS.getOperand(0);
5298
5299 SDValue Res = DAG.getNode(Opc, SL, VT, LHS, MHS, RHS);
5300 if (Res.getOpcode() != Opc)
5301 return SDValue(); // Op got folded away.
5302 if (!N0.hasOneUse())
5303 DAG.ReplaceAllUsesWith(N0, DAG.getNode(ISD::FNEG, SL, VT, Res));
5304 return Res;
5305 }
5306 case ISD::FMAXNUM:
5307 case ISD::FMINNUM:
5308 case ISD::FMAXNUM_IEEE:
5309 case ISD::FMINNUM_IEEE:
5310 case ISD::FMINIMUM:
5311 case ISD::FMAXIMUM:
5312 case ISD::FMINIMUMNUM:
5313 case ISD::FMAXIMUMNUM:
5314 case AMDGPUISD::FMAX_LEGACY:
5315 case AMDGPUISD::FMIN_LEGACY: {
5316 // fneg (fmaxnum x, y) -> fminnum (fneg x), (fneg y)
5317 // fneg (fminnum x, y) -> fmaxnum (fneg x), (fneg y)
5318 // fneg (fmax_legacy x, y) -> fmin_legacy (fneg x), (fneg y)
5319 // fneg (fmin_legacy x, y) -> fmax_legacy (fneg x), (fneg y)
5320
5321 SDValue LHS = N0.getOperand(0);
5322 SDValue RHS = N0.getOperand(1);
5323
5324 // 0 doesn't have a negated inline immediate.
5325 // TODO: This constant check should be generalized to other operations.
5327 return SDValue();
5328
5329 // Swapping min<->max flips which operand a signed zero tie selects.
5330 if ((Opc == AMDGPUISD::FMIN_LEGACY || Opc == AMDGPUISD::FMAX_LEGACY) &&
5331 !canIgnoreLegacyMinMaxTies(DAG, N0->getFlags(), LHS, RHS))
5332 return SDValue();
5333
5334 SDValue NegLHS = DAG.getNode(ISD::FNEG, SL, VT, LHS);
5335 SDValue NegRHS = DAG.getNode(ISD::FNEG, SL, VT, RHS);
5336 unsigned Opposite = inverseMinMax(Opc);
5337
5338 SDValue Res = DAG.getNode(Opposite, SL, VT, NegLHS, NegRHS, N0->getFlags());
5339 if (Res.getOpcode() != Opposite)
5340 return SDValue(); // Op got folded away.
5341 if (!N0.hasOneUse())
5342 DAG.ReplaceAllUsesWith(N0, DAG.getNode(ISD::FNEG, SL, VT, Res));
5343 return Res;
5344 }
5345 case AMDGPUISD::FMED3: {
5346 // med3 sorts a NaN input as smaller than everything regardless of its sign,
5347 // so negating all operands does not sign-flip the median when an input may
5348 // be NaN.
5349 if (!N0->getFlags().hasNoNaNs())
5350 return SDValue();
5351
5352 SDValue Ops[3];
5353 for (unsigned I = 0; I < 3; ++I)
5354 Ops[I] = DAG.getNode(ISD::FNEG, SL, VT, N0->getOperand(I), N0->getFlags());
5355
5356 SDValue Res = DAG.getNode(AMDGPUISD::FMED3, SL, VT, Ops, N0->getFlags());
5357 if (Res.getOpcode() != AMDGPUISD::FMED3)
5358 return SDValue(); // Op got folded away.
5359
5360 if (!N0.hasOneUse()) {
5361 SDValue Neg = DAG.getNode(ISD::FNEG, SL, VT, Res);
5362 DAG.ReplaceAllUsesWith(N0, Neg);
5363
5364 for (SDNode *U : Neg->users())
5365 DCI.AddToWorklist(U);
5366 }
5367
5368 return Res;
5369 }
5370 case ISD::FP_EXTEND:
5371 case ISD::FTRUNC:
5372 case ISD::FRINT:
5373 case ISD::FNEARBYINT: // XXX - Should fround be handled?
5374 case ISD::FROUNDEVEN:
5375 case ISD::FSIN:
5376 case ISD::FCANONICALIZE:
5377 case AMDGPUISD::RCP:
5378 case AMDGPUISD::RCP_LEGACY:
5379 case AMDGPUISD::RCP_IFLAG:
5380 case AMDGPUISD::SIN_HW: {
5381 SDValue CvtSrc = N0.getOperand(0);
5382 if (CvtSrc.getOpcode() == ISD::FNEG) {
5383 // (fneg (fp_extend (fneg x))) -> (fp_extend x)
5384 // (fneg (rcp (fneg x))) -> (rcp x)
5385 return DAG.getNode(Opc, SL, VT, CvtSrc.getOperand(0));
5386 }
5387
5388 if (!N0.hasOneUse())
5389 return SDValue();
5390
5391 // (fneg (fp_extend x)) -> (fp_extend (fneg x))
5392 // (fneg (rcp x)) -> (rcp (fneg x))
5393 SDValue Neg = DAG.getNode(ISD::FNEG, SL, CvtSrc.getValueType(), CvtSrc);
5394 return DAG.getNode(Opc, SL, VT, Neg, N0->getFlags());
5395 }
5396 case ISD::FP_ROUND: {
5397 SDValue CvtSrc = N0.getOperand(0);
5398
5399 if (CvtSrc.getOpcode() == ISD::FNEG) {
5400 // (fneg (fp_round (fneg x))) -> (fp_round x)
5401 return DAG.getNode(ISD::FP_ROUND, SL, VT,
5402 CvtSrc.getOperand(0), N0.getOperand(1));
5403 }
5404
5405 if (!N0.hasOneUse())
5406 return SDValue();
5407
5408 // (fneg (fp_round x)) -> (fp_round (fneg x))
5409 SDValue Neg = DAG.getNode(ISD::FNEG, SL, CvtSrc.getValueType(), CvtSrc);
5410 return DAG.getNode(ISD::FP_ROUND, SL, VT, Neg, N0.getOperand(1));
5411 }
5412 case ISD::FP16_TO_FP: {
5413 // v_cvt_f32_f16 supports source modifiers on pre-VI targets without legal
5414 // f16, but legalization of f16 fneg ends up pulling it out of the source.
5415 // Put the fneg back as a legal source operation that can be matched later.
5416 SDLoc SL(N);
5417
5418 SDValue Src = N0.getOperand(0);
5419 EVT SrcVT = Src.getValueType();
5420
5421 // fneg (fp16_to_fp x) -> fp16_to_fp (xor x, 0x8000)
5422 SDValue IntFNeg = DAG.getNode(ISD::XOR, SL, SrcVT, Src,
5423 DAG.getConstant(0x8000, SL, SrcVT));
5424 return DAG.getNode(ISD::FP16_TO_FP, SL, N->getValueType(0), IntFNeg);
5425 }
5426 case ISD::SELECT: {
5427 // fneg (select c, a, b) -> select c, (fneg a), (fneg b)
5428 // TODO: Invert conditions of foldFreeOpFromSelect
5429 return SDValue();
5430 }
5431 case ISD::BITCAST: {
5432 SDLoc SL(N);
5433 SDValue BCSrc = N0.getOperand(0);
5434 if (BCSrc.getOpcode() == ISD::BUILD_VECTOR) {
5435 SDValue HighBits = BCSrc.getOperand(BCSrc.getNumOperands() - 1);
5436 if (VT != MVT::f64 || HighBits.getValueType().getSizeInBits() != 32 ||
5437 !fnegFoldsIntoOp(HighBits.getNode()))
5438 return SDValue();
5439
5440 // f64 fneg only really needs to operate on the high half of of the
5441 // register, so try to force it to an f32 operation to help make use of
5442 // source modifiers.
5443 //
5444 //
5445 // fneg (f64 (bitcast (build_vector x, y))) ->
5446 // f64 (bitcast (build_vector (bitcast i32:x to f32),
5447 // (fneg (bitcast i32:y to f32)))
5448
5449 SDValue CastHi = DAG.getNode(ISD::BITCAST, SL, MVT::f32, HighBits);
5450 SDValue NegHi = DAG.getNode(ISD::FNEG, SL, MVT::f32, CastHi);
5451 SDValue CastBack =
5452 DAG.getNode(ISD::BITCAST, SL, HighBits.getValueType(), NegHi);
5453
5455 Ops.back() = CastBack;
5456 DCI.AddToWorklist(NegHi.getNode());
5457 SDValue Build =
5458 DAG.getNode(ISD::BUILD_VECTOR, SL, BCSrc.getValueType(), Ops);
5459 SDValue Result = DAG.getNode(ISD::BITCAST, SL, VT, Build);
5460
5461 if (!N0.hasOneUse())
5462 DAG.ReplaceAllUsesWith(N0, DAG.getNode(ISD::FNEG, SL, VT, Result));
5463 return Result;
5464 }
5465
5466 if (BCSrc.getOpcode() == ISD::SELECT && VT == MVT::f32 &&
5467 BCSrc.hasOneUse()) {
5468 // fneg (bitcast (f32 (select cond, i32:lhs, i32:rhs))) ->
5469 // select cond, (bitcast i32:lhs to f32), (bitcast i32:rhs to f32)
5470
5471 // TODO: Cast back result for multiple uses is beneficial in some cases.
5472
5473 SDValue LHS =
5474 DAG.getNode(ISD::BITCAST, SL, MVT::f32, BCSrc.getOperand(1));
5475 SDValue RHS =
5476 DAG.getNode(ISD::BITCAST, SL, MVT::f32, BCSrc.getOperand(2));
5477
5478 SDValue NegLHS = DAG.getNode(ISD::FNEG, SL, MVT::f32, LHS);
5479 SDValue NegRHS = DAG.getNode(ISD::FNEG, SL, MVT::f32, RHS);
5480
5481 return DAG.getNode(ISD::SELECT, SL, MVT::f32, BCSrc.getOperand(0), NegLHS,
5482 NegRHS);
5483 }
5484
5485 return SDValue();
5486 }
5487 default:
5488 return SDValue();
5489 }
5490}
5491
5493 DAGCombinerInfo &DCI) const {
5494 SelectionDAG &DAG = DCI.DAG;
5495 SDValue N0 = N->getOperand(0);
5496
5497 if (!N0.hasOneUse())
5498 return SDValue();
5499
5500 switch (N0.getOpcode()) {
5501 case ISD::FP16_TO_FP: {
5502 assert(!isTypeLegal(MVT::f16) && "should only see if f16 is illegal");
5503 SDLoc SL(N);
5504 SDValue Src = N0.getOperand(0);
5505 EVT SrcVT = Src.getValueType();
5506
5507 // fabs (fp16_to_fp x) -> fp16_to_fp (and x, 0x7fff)
5508 SDValue IntFAbs = DAG.getNode(ISD::AND, SL, SrcVT, Src,
5509 DAG.getConstant(0x7fff, SL, SrcVT));
5510 return DAG.getNode(ISD::FP16_TO_FP, SL, N->getValueType(0), IntFAbs);
5511 }
5512 case ISD::FP_ROUND: {
5513 SDLoc SL(N);
5514 SDValue CvtSrc = N0.getOperand(0);
5515
5516 // fabs (fp_round x) -> fp_round (fabs x)
5517 SDValue Abs = DAG.getNode(ISD::FABS, SL, CvtSrc.getValueType(), CvtSrc,
5518 N->getFlags());
5519 return DAG.getNode(ISD::FP_ROUND, SL, N->getValueType(0), Abs,
5520 N0.getOperand(1), N0->getFlags());
5521 }
5522 default:
5523 return SDValue();
5524 }
5525}
5526
5528 DAGCombinerInfo &DCI) const {
5529 const auto *CFP = dyn_cast<ConstantFPSDNode>(N->getOperand(0));
5530 if (!CFP)
5531 return SDValue();
5532
5533 std::optional<APFloat> Result = AMDGPU::evaluateRcp(CFP->getValueAPF());
5534 if (!Result)
5535 return SDValue();
5536
5537 return DCI.DAG.getConstantFP(*Result, SDLoc(N), N->getValueType(0));
5538}
5539
5541 if (!Subtarget->isGCN())
5542 return false;
5543
5546 auto &ST = DAG.getSubtarget<GCNSubtarget>();
5547 const auto *TII = ST.getInstrInfo();
5548
5549 if (!ST.hasVMovB64Inst() || (!SDConstant && !SDFPConstant))
5550 return false;
5551
5552 if (ST.has64BitLiterals())
5553 return true;
5554
5555 if (SDConstant) {
5556 const APInt &APVal = SDConstant->getAPIntValue();
5557 return isUInt<32>(APVal.getZExtValue()) || TII->isInlineConstant(APVal);
5558 }
5559
5560 APInt Val = SDFPConstant->getValueAPF().bitcastToAPInt();
5561 return isUInt<32>(Val.getZExtValue()) || TII->isInlineConstant(Val);
5562}
5563
5565 DAGCombinerInfo &DCI) const {
5566 SelectionDAG &DAG = DCI.DAG;
5567 SDLoc DL(N);
5568
5569 switch(N->getOpcode()) {
5570 default:
5571 break;
5572 case ISD::BITCAST: {
5573 EVT DestVT = N->getValueType(0);
5574
5575 // Push casts through vector builds. This helps avoid emitting a large
5576 // number of copies when materializing floating point vector constants.
5577 //
5578 // vNt1 bitcast (vNt0 (build_vector t0:x, t0:y)) =>
5579 // vnt1 = build_vector (t1 (bitcast t0:x)), (t1 (bitcast t0:y))
5580 if (DestVT.isVector()) {
5581 SDValue Src = N->getOperand(0);
5582 if (Src.getOpcode() == ISD::BUILD_VECTOR &&
5585 EVT SrcVT = Src.getValueType();
5586 unsigned NElts = DestVT.getVectorNumElements();
5587
5588 if (SrcVT.getVectorNumElements() == NElts) {
5589 EVT DestEltVT = DestVT.getVectorElementType();
5590
5591 SmallVector<SDValue, 8> CastedElts;
5592 SDLoc SL(N);
5593 for (unsigned I = 0, E = SrcVT.getVectorNumElements(); I != E; ++I) {
5594 SDValue Elt = Src.getOperand(I);
5595 CastedElts.push_back(DAG.getNode(ISD::BITCAST, DL, DestEltVT, Elt));
5596 }
5597
5598 return DAG.getBuildVector(DestVT, SL, CastedElts);
5599 }
5600 }
5601 }
5602
5603 if (DestVT.getSizeInBits() != 64 || !DestVT.isVector())
5604 break;
5605
5606 // Fold bitcasts of constants.
5607 //
5608 // v2i32 (bitcast i64:k) -> build_vector lo_32(k), hi_32(k)
5609 // TODO: Generalize and move to DAGCombiner
5610 SDValue Src = N->getOperand(0);
5612 SDLoc SL(N);
5613 if (isInt64ImmLegal(C, DAG))
5614 break;
5615 uint64_t CVal = C->getZExtValue();
5616 SDValue BV = DAG.getNode(ISD::BUILD_VECTOR, SL, MVT::v2i32,
5617 DAG.getConstant(Lo_32(CVal), SL, MVT::i32),
5618 DAG.getConstant(Hi_32(CVal), SL, MVT::i32));
5619 return DAG.getNode(ISD::BITCAST, SL, DestVT, BV);
5620 }
5621
5623 const APInt &Val = C->getValueAPF().bitcastToAPInt();
5624 SDLoc SL(N);
5625 if (isInt64ImmLegal(C, DAG))
5626 break;
5627 uint64_t CVal = Val.getZExtValue();
5628 SDValue Vec = DAG.getNode(ISD::BUILD_VECTOR, SL, MVT::v2i32,
5629 DAG.getConstant(Lo_32(CVal), SL, MVT::i32),
5630 DAG.getConstant(Hi_32(CVal), SL, MVT::i32));
5631
5632 return DAG.getNode(ISD::BITCAST, SL, DestVT, Vec);
5633 }
5634
5635 break;
5636 }
5637 case ISD::SHL:
5638 case ISD::SRA:
5639 case ISD::SRL: {
5640 // Range metadata can be invalidated when loads are converted to legal types
5641 // (e.g. v2i64 -> v4i32).
5642 // Try to convert vector shl/sra/srl before type legalization so that range
5643 // metadata can be utilized.
5644 if (!(N->getValueType(0).isVector() &&
5647 break;
5648 if (N->getOpcode() == ISD::SHL)
5649 return performShlCombine(N, DCI);
5650 if (N->getOpcode() == ISD::SRA)
5651 return performSraCombine(N, DCI);
5652 return performSrlCombine(N, DCI);
5653 }
5654 case ISD::TRUNCATE:
5655 return performTruncateCombine(N, DCI);
5656 case ISD::MUL:
5657 return performMulCombine(N, DCI);
5658 case AMDGPUISD::MUL_U24:
5659 case AMDGPUISD::MUL_I24: {
5660 if (SDValue Simplified = simplifyMul24(N, DCI))
5661 return Simplified;
5662 break;
5663 }
5664 case AMDGPUISD::MULHI_I24:
5665 case AMDGPUISD::MULHI_U24:
5666 return simplifyMul24(N, DCI);
5667 case ISD::SMUL_LOHI:
5668 case ISD::UMUL_LOHI:
5669 return performMulLoHiCombine(N, DCI);
5670 case ISD::MULHS:
5671 return performMulhsCombine(N, DCI);
5672 case ISD::MULHU:
5673 return performMulhuCombine(N, DCI);
5674 case ISD::SELECT:
5675 return performSelectCombine(N, DCI);
5676 case ISD::FNEG:
5677 return performFNegCombine(N, DCI);
5678 case ISD::FABS:
5679 return performFAbsCombine(N, DCI);
5680 case AMDGPUISD::BFE_I32:
5681 case AMDGPUISD::BFE_U32: {
5682 assert(N->getValueType(0) == MVT::i32 &&
5683 "BFE_I32/BFE_U32 is a 32-bit operation");
5684 ConstantSDNode *Width = dyn_cast<ConstantSDNode>(N->getOperand(2));
5685 if (!Width)
5686 break;
5687
5688 uint32_t WidthVal = Width->getZExtValue() & 0x1f;
5689 if (WidthVal == 0)
5690 return DAG.getConstant(0, DL, MVT::i32);
5691
5693 if (!Offset)
5694 break;
5695
5696 SDValue BitsFrom = N->getOperand(0);
5697 uint32_t OffsetVal = Offset->getZExtValue() & 0x1f;
5698
5699 bool Signed = N->getOpcode() == AMDGPUISD::BFE_I32;
5700
5701 if (OffsetVal == 0) {
5702 // This is already sign / zero extended, so try to fold away extra BFEs.
5703 EVT SmallVT = EVT::getIntegerVT(*DAG.getContext(), WidthVal);
5704 if (Signed) {
5705 if (DAG.ComputeNumSignBits(BitsFrom) >= 32 - WidthVal + 1)
5706 return BitsFrom;
5707
5708 // This is a sign_extend_inreg. Replace it to take advantage of existing
5709 // DAG Combines. If not eliminated, we will match back to BFE during
5710 // selection.
5711
5712 // TODO: The sext_inreg of extended types ends, although we can could
5713 // handle them in a single BFE.
5714 return DAG.getNode(ISD::SIGN_EXTEND_INREG, DL, MVT::i32, BitsFrom,
5715 DAG.getValueType(SmallVT));
5716 }
5717
5718 if (DAG.MaskedValueIsZero(BitsFrom,
5719 APInt::getHighBitsSet(32, 32 - WidthVal)))
5720 return BitsFrom;
5721
5722 return DAG.getZeroExtendInReg(BitsFrom, DL, SmallVT);
5723 }
5724
5725 if (ConstantSDNode *CVal = dyn_cast<ConstantSDNode>(BitsFrom)) {
5726 if (Signed) {
5727 return constantFoldBFE<int32_t>(DAG,
5728 CVal->getSExtValue(),
5729 OffsetVal,
5730 WidthVal,
5731 DL);
5732 }
5733
5734 return constantFoldBFE<uint32_t>(DAG,
5735 CVal->getZExtValue(),
5736 OffsetVal,
5737 WidthVal,
5738 DL);
5739 }
5740
5741 if ((OffsetVal + WidthVal) >= 32 &&
5742 !(OffsetVal == 16 && WidthVal == 16 && Subtarget->hasSDWA())) {
5743 SDValue ShiftVal = DAG.getConstant(OffsetVal, DL, MVT::i32);
5744 return DAG.getNode(Signed ? ISD::SRA : ISD::SRL, DL, MVT::i32,
5745 BitsFrom, ShiftVal);
5746 }
5747
5748 if (BitsFrom.hasOneUse()) {
5749 APInt Demanded = APInt::getBitsSet(32,
5750 OffsetVal,
5751 OffsetVal + WidthVal);
5752
5755 !DCI.isBeforeLegalizeOps());
5756 const TargetLowering &TLI = DAG.getTargetLoweringInfo();
5757 if (TLI.ShrinkDemandedConstant(BitsFrom, Demanded, TLO) ||
5758 TLI.SimplifyDemandedBits(BitsFrom, Demanded, Known, TLO)) {
5759 DCI.CommitTargetLoweringOpt(TLO);
5760 }
5761 }
5762
5763 break;
5764 }
5765 case ISD::LOAD:
5766 return performLoadCombine(N, DCI);
5767 case ISD::STORE:
5768 return performStoreCombine(N, DCI);
5769 case AMDGPUISD::RCP:
5770 case AMDGPUISD::RCP_IFLAG:
5771 return performRcpCombine(N, DCI);
5772 case ISD::AssertZext:
5773 case ISD::AssertSext:
5774 return performAssertSZExtCombine(N, DCI);
5776 return performIntrinsicWOChainCombine(N, DCI);
5777 case AMDGPUISD::FMAD_FTZ: {
5778 SDValue N0 = N->getOperand(0);
5779 SDValue N1 = N->getOperand(1);
5780 SDValue N2 = N->getOperand(2);
5781 EVT VT = N->getValueType(0);
5782
5783 // FMAD_FTZ is a FMAD + flush denormals to zero.
5784 // We flush the inputs, the intermediate step, and the output.
5788 if (N0CFP && N1CFP && N2CFP) {
5789 const auto FTZ = [](const APFloat &V) {
5790 if (V.isDenormal()) {
5791 APFloat Zero(V.getSemantics(), 0);
5792 return V.isNegative() ? -Zero : Zero;
5793 }
5794 return V;
5795 };
5796
5797 APFloat V0 = FTZ(N0CFP->getValueAPF());
5798 APFloat V1 = FTZ(N1CFP->getValueAPF());
5799 APFloat V2 = FTZ(N2CFP->getValueAPF());
5800 V0.multiply(V1, APFloat::rmNearestTiesToEven);
5801 V0 = FTZ(V0);
5802 V0.add(V2, APFloat::rmNearestTiesToEven);
5803 return DAG.getConstantFP(FTZ(V0), DL, VT);
5804 }
5805 break;
5806 }
5807 }
5808 return SDValue();
5809}
5810
5812 SDValue Op, const APInt &OriginalDemandedBits,
5813 const APInt &OriginalDemandedElts, KnownBits &Known, TargetLoweringOpt &TLO,
5814 unsigned Depth) const {
5815 switch (Op.getOpcode()) {
5817 switch (Op.getConstantOperandVal(0)) {
5818 case Intrinsic::amdgcn_readfirstlane:
5819 case Intrinsic::amdgcn_readlane:
5820 case Intrinsic::amdgcn_wwm: {
5821 if (SimplifyDemandedBits(Op.getOperand(1), OriginalDemandedBits,
5822 OriginalDemandedElts, Known, TLO, Depth + 1))
5823 return true;
5824 break;
5825 }
5826 case Intrinsic::amdgcn_set_inactive:
5827 case Intrinsic::amdgcn_set_inactive_chain_arg: {
5828 // The result is operand 1 in active lanes and operand 2 in inactive
5829 // lanes, so the known bits are the intersection of both operands.
5830 KnownBits KnownValue, KnownInactive;
5831 if (SimplifyDemandedBits(Op.getOperand(1), OriginalDemandedBits,
5832 OriginalDemandedElts, KnownValue, TLO,
5833 Depth + 1))
5834 return true;
5835 if (SimplifyDemandedBits(Op.getOperand(2), OriginalDemandedBits,
5836 OriginalDemandedElts, KnownInactive, TLO,
5837 Depth + 1))
5838 return true;
5839 Known = KnownValue.intersectWith(KnownInactive);
5840 break;
5841 }
5842 default:
5843 break;
5844 }
5845 break;
5846 }
5847 default:
5848 break;
5849 }
5850
5851 return false;
5852}
5853
5854//===----------------------------------------------------------------------===//
5855// Helper functions
5856//===----------------------------------------------------------------------===//
5857
5859 const TargetRegisterClass *RC,
5860 Register Reg, EVT VT,
5861 const SDLoc &SL,
5862 bool RawReg) const {
5864 MachineRegisterInfo &MRI = MF.getRegInfo();
5865 Register VReg;
5866
5867 if (!MRI.isLiveIn(Reg)) {
5868 VReg = MRI.createVirtualRegister(RC);
5869 MRI.addLiveIn(Reg, VReg);
5870 } else {
5871 VReg = MRI.getLiveInVirtReg(Reg);
5872 }
5873
5874 if (RawReg)
5875 return DAG.getRegister(VReg, VT);
5876
5877 return DAG.getCopyFromReg(DAG.getEntryNode(), SL, VReg, VT);
5878}
5879
5880// This may be called multiple times, and nothing prevents creating multiple
5881// objects at the same offset. See if we already defined this object.
5883 int64_t Offset) {
5884 for (int I = MFI.getObjectIndexBegin(); I < 0; ++I) {
5885 if (MFI.getObjectOffset(I) == Offset) {
5886 assert(MFI.getObjectSize(I) == Size);
5887 return I;
5888 }
5889 }
5890
5891 return MFI.CreateFixedObject(Size, Offset, true);
5892}
5893
5895 EVT VT,
5896 const SDLoc &SL,
5897 int64_t Offset) const {
5899 MachineFrameInfo &MFI = MF.getFrameInfo();
5900 int FI = getOrCreateFixedStackObject(MFI, VT.getStoreSize(), Offset);
5901
5902 auto SrcPtrInfo = MachinePointerInfo::getStack(MF, Offset);
5903 SDValue Ptr = DAG.getFrameIndex(FI, MVT::i32);
5904
5905 return DAG.getLoad(VT, SL, DAG.getEntryNode(), Ptr, SrcPtrInfo, Align(4),
5908}
5909
5911 const SDLoc &SL,
5912 SDValue Chain,
5913 SDValue ArgVal,
5914 int64_t Offset) const {
5918
5919 SDValue Ptr = DAG.getConstant(Offset, SL, MVT::i32);
5920 // Stores to the argument stack area are relative to the stack pointer.
5921 SDValue SP =
5922 DAG.getCopyFromReg(Chain, SL, Info->getStackPtrOffsetReg(), MVT::i32);
5923 Ptr = DAG.getNode(ISD::ADD, SL, MVT::i32, SP, Ptr);
5924 SDValue Store = DAG.getStore(Chain, SL, ArgVal, Ptr, DstInfo, Align(4),
5926 return Store;
5927}
5928
5930 const TargetRegisterClass *RC,
5931 EVT VT, const SDLoc &SL,
5932 const ArgDescriptor &Arg) const {
5933 assert(Arg && "Attempting to load missing argument");
5934
5935 SDValue V = Arg.isRegister() ?
5936 CreateLiveInRegister(DAG, RC, Arg.getRegister(), VT, SL) :
5937 loadStackInputValue(DAG, VT, SL, Arg.getStackOffset());
5938
5939 if (!Arg.isMasked())
5940 return V;
5941
5942 unsigned Mask = Arg.getMask();
5943 unsigned Shift = llvm::countr_zero<unsigned>(Mask);
5944 V = DAG.getNode(ISD::SRL, SL, VT, V,
5945 DAG.getShiftAmountConstant(Shift, VT, SL));
5946 return DAG.getNode(ISD::AND, SL, VT, V,
5947 DAG.getConstant(Mask >> Shift, SL, VT));
5948}
5949
5951 uint64_t ExplicitKernArgSize, const ImplicitParameter Param) const {
5952 unsigned ExplicitArgOffset = Subtarget->getExplicitKernelArgOffset();
5953 const Align Alignment = Subtarget->getAlignmentForImplicitArgPtr();
5954 uint64_t ArgOffset =
5955 alignTo(ExplicitKernArgSize, Alignment) + ExplicitArgOffset;
5956 switch (Param) {
5957 case FIRST_IMPLICIT:
5958 return ArgOffset;
5959 case PRIVATE_BASE:
5961 case SHARED_BASE:
5962 return ArgOffset + AMDGPU::ImplicitArg::SHARED_BASE_OFFSET;
5963 case QUEUE_PTR:
5964 return ArgOffset + AMDGPU::ImplicitArg::QUEUE_PTR_OFFSET;
5965 }
5966 llvm_unreachable("unexpected implicit parameter type");
5967}
5968
5975
5977 SelectionDAG &DAG, int Enabled,
5978 int &RefinementSteps,
5979 bool &UseOneConstNR,
5980 bool Reciprocal) const {
5981 EVT VT = Operand.getValueType();
5982
5983 if (VT == MVT::f32) {
5984 RefinementSteps = 0;
5985 return DAG.getNode(AMDGPUISD::RSQ, SDLoc(Operand), VT, Operand);
5986 }
5987
5988 // TODO: There is also f64 rsq instruction, but the documentation is less
5989 // clear on its precision.
5990
5991 return SDValue();
5992}
5993
5995 SelectionDAG &DAG, int Enabled,
5996 int &RefinementSteps) const {
5997 EVT VT = Operand.getValueType();
5998
5999 if (VT == MVT::f32) {
6000 // Reciprocal, < 1 ulp error.
6001 //
6002 // This reciprocal approximation converges to < 0.5 ulp error with one
6003 // newton rhapson performed with two fused multiple adds (FMAs).
6004
6005 RefinementSteps = 0;
6006 return DAG.getNode(AMDGPUISD::RCP, SDLoc(Operand), VT, Operand);
6007 }
6008
6009 // TODO: There is also f64 rcp instruction, but the documentation is less
6010 // clear on its precision.
6011
6012 return SDValue();
6013}
6014
6015static unsigned workitemIntrinsicDim(unsigned ID) {
6016 switch (ID) {
6017 case Intrinsic::amdgcn_workitem_id_x:
6018 return 0;
6019 case Intrinsic::amdgcn_workitem_id_y:
6020 return 1;
6021 case Intrinsic::amdgcn_workitem_id_z:
6022 return 2;
6023 default:
6024 llvm_unreachable("not a workitem intrinsic");
6025 }
6026}
6027
6029 const SDValue Op, KnownBits &Known,
6030 const APInt &DemandedElts, const SelectionDAG &DAG, unsigned Depth) const {
6031
6032 Known.resetAll(); // Don't know anything.
6033
6034 unsigned Opc = Op.getOpcode();
6035
6036 switch (Opc) {
6037 default:
6038 break;
6039 case AMDGPUISD::CARRY:
6040 case AMDGPUISD::BORROW: {
6041 Known.Zero = APInt::getHighBitsSet(32, 31);
6042 break;
6043 }
6044
6045 case AMDGPUISD::BFE_I32:
6046 case AMDGPUISD::BFE_U32: {
6047 ConstantSDNode *CWidth = dyn_cast<ConstantSDNode>(Op.getOperand(2));
6048 if (!CWidth)
6049 return;
6050
6051 uint32_t Width = CWidth->getZExtValue() & 0x1f;
6052
6053 if (Opc == AMDGPUISD::BFE_U32)
6054 Known.Zero = APInt::getHighBitsSet(32, 32 - Width);
6055
6056 break;
6057 }
6058 case AMDGPUISD::FP_TO_FP16: {
6059 unsigned BitWidth = Known.getBitWidth();
6060
6061 // High bits are zero.
6063 break;
6064 }
6065 case AMDGPUISD::MUL_U24:
6066 case AMDGPUISD::MUL_I24: {
6067 KnownBits LHSKnown = DAG.computeKnownBits(Op.getOperand(0), Depth + 1);
6068 KnownBits RHSKnown = DAG.computeKnownBits(Op.getOperand(1), Depth + 1);
6069 unsigned BitWidth = Op.getScalarValueSizeInBits();
6070
6071 // Sign/Zero extend from 24 bits.
6072 if (Opc == AMDGPUISD::MUL_I24) {
6073 LHSKnown = LHSKnown.trunc(24).sext(BitWidth);
6074 RHSKnown = RHSKnown.trunc(24).sext(BitWidth);
6075 } else {
6076 LHSKnown = LHSKnown.trunc(24).zext(BitWidth);
6077 RHSKnown = RHSKnown.trunc(24).zext(BitWidth);
6078 }
6079
6080 // TODO: SelfMultiply can be poison, but not undef.
6081 bool SelfMultiply = Op.getOperand(0) == Op.getOperand(1);
6082 if (SelfMultiply)
6083 SelfMultiply &= DAG.isGuaranteedNotToBeUndefOrPoison(
6084 Op.getOperand(0), DemandedElts, UndefPoisonKind::UndefOrPoison,
6085 Depth + 1);
6086
6087 Known = KnownBits::mul(LHSKnown, RHSKnown, SelfMultiply);
6088 break;
6089 }
6090 case AMDGPUISD::PERM: {
6091 ConstantSDNode *CMask = dyn_cast<ConstantSDNode>(Op.getOperand(2));
6092 if (!CMask)
6093 return;
6094
6095 KnownBits LHSKnown = DAG.computeKnownBits(Op.getOperand(0), Depth + 1);
6096 KnownBits RHSKnown = DAG.computeKnownBits(Op.getOperand(1), Depth + 1);
6097 unsigned Sel = CMask->getZExtValue();
6098
6099 for (unsigned I = 0; I < 32; I += 8) {
6100 unsigned SelBits = Sel & 0xff;
6101 if (SelBits < 4) {
6102 SelBits *= 8;
6103 Known.One |= ((RHSKnown.One.getZExtValue() >> SelBits) & 0xff) << I;
6104 Known.Zero |= ((RHSKnown.Zero.getZExtValue() >> SelBits) & 0xff) << I;
6105 } else if (SelBits < 7) {
6106 SelBits = (SelBits & 3) * 8;
6107 Known.One |= ((LHSKnown.One.getZExtValue() >> SelBits) & 0xff) << I;
6108 Known.Zero |= ((LHSKnown.Zero.getZExtValue() >> SelBits) & 0xff) << I;
6109 } else if (SelBits == 0x0c) {
6110 Known.Zero |= 0xFFull << I;
6111 } else if (SelBits > 0x0c) {
6112 Known.One |= 0xFFull << I;
6113 }
6114 Sel >>= 8;
6115 }
6116 break;
6117 }
6118 case AMDGPUISD::BUFFER_LOAD_UBYTE: {
6119 Known.Zero.setHighBits(24);
6120 break;
6121 }
6122 case AMDGPUISD::BUFFER_LOAD_USHORT: {
6123 Known.Zero.setHighBits(16);
6124 break;
6125 }
6126 case AMDGPUISD::LDS: {
6127 auto *GA = cast<GlobalAddressSDNode>(Op.getOperand(0).getNode());
6128 Align Alignment = GA->getGlobal()->getPointerAlignment(DAG.getDataLayout());
6129
6130 Known.Zero.setHighBits(16);
6131 Known.Zero.setLowBits(Log2(Alignment));
6132 break;
6133 }
6134 case AMDGPUISD::SMIN3:
6135 case AMDGPUISD::SMAX3:
6136 case AMDGPUISD::SMED3:
6137 case AMDGPUISD::UMIN3:
6138 case AMDGPUISD::UMAX3:
6139 case AMDGPUISD::UMED3: {
6140 KnownBits Known2 = DAG.computeKnownBits(Op.getOperand(2), Depth + 1);
6141 if (Known2.isUnknown())
6142 break;
6143
6144 KnownBits Known1 = DAG.computeKnownBits(Op.getOperand(1), Depth + 1);
6145 if (Known1.isUnknown())
6146 break;
6147
6148 KnownBits Known0 = DAG.computeKnownBits(Op.getOperand(0), Depth + 1);
6149 if (Known0.isUnknown())
6150 break;
6151
6152 // TODO: Handle LeadZero/LeadOne from UMIN/UMAX handling.
6153 Known.Zero = Known0.Zero & Known1.Zero & Known2.Zero;
6154 Known.One = Known0.One & Known1.One & Known2.One;
6155 break;
6156 }
6158 unsigned IID = Op.getConstantOperandVal(0);
6159 switch (IID) {
6160 case Intrinsic::amdgcn_workitem_id_x:
6161 case Intrinsic::amdgcn_workitem_id_y:
6162 case Intrinsic::amdgcn_workitem_id_z: {
6163 unsigned MaxValue = Subtarget->getMaxWorkitemID(
6165 Known.Zero.setHighBits(llvm::countl_zero(MaxValue));
6166 break;
6167 }
6168 case Intrinsic::amdgcn_readfirstlane:
6169 case Intrinsic::amdgcn_readlane:
6170 // Result is the data operand's value from some lane.
6171 Known = DAG.computeKnownBits(Op.getOperand(1), DemandedElts, Depth + 1);
6172 break;
6173 default:
6174 break;
6175 }
6176 }
6177 }
6178}
6179
6181 SDValue Op, const APInt &DemandedElts, const SelectionDAG &DAG,
6182 unsigned Depth) const {
6183 switch (Op.getOpcode()) {
6184 case AMDGPUISD::BFE_I32: {
6185 ConstantSDNode *Width = dyn_cast<ConstantSDNode>(Op.getOperand(2));
6186 if (!Width)
6187 return 1;
6188
6189 unsigned SignBits = 32 - (Width->getZExtValue() & 0x1f) + 1;
6190 if (!isNullConstant(Op.getOperand(1)))
6191 return SignBits;
6192
6193 // TODO: Could probably figure something out with non-0 offsets.
6194 unsigned Op0SignBits = DAG.ComputeNumSignBits(Op.getOperand(0), Depth + 1);
6195 return std::max(SignBits, Op0SignBits);
6196 }
6197
6198 case AMDGPUISD::BFE_U32: {
6199 ConstantSDNode *Width = dyn_cast<ConstantSDNode>(Op.getOperand(2));
6200 return Width ? 32 - (Width->getZExtValue() & 0x1f) : 1;
6201 }
6202
6203 case AMDGPUISD::CARRY:
6204 case AMDGPUISD::BORROW:
6205 return 31;
6206 case AMDGPUISD::BUFFER_LOAD_BYTE:
6207 return 25;
6208 case AMDGPUISD::BUFFER_LOAD_SHORT:
6209 return 17;
6210 case AMDGPUISD::BUFFER_LOAD_UBYTE:
6211 return 24;
6212 case AMDGPUISD::BUFFER_LOAD_USHORT:
6213 return 16;
6214 case AMDGPUISD::FP_TO_FP16:
6215 return 16;
6216 case AMDGPUISD::SMIN3:
6217 case AMDGPUISD::SMAX3:
6218 case AMDGPUISD::SMED3:
6219 case AMDGPUISD::UMIN3:
6220 case AMDGPUISD::UMAX3:
6221 case AMDGPUISD::UMED3: {
6222 unsigned Tmp2 = DAG.ComputeNumSignBits(Op.getOperand(2), Depth + 1);
6223 if (Tmp2 == 1)
6224 return 1; // Early out.
6225
6226 unsigned Tmp1 = DAG.ComputeNumSignBits(Op.getOperand(1), Depth + 1);
6227 if (Tmp1 == 1)
6228 return 1; // Early out.
6229
6230 unsigned Tmp0 = DAG.ComputeNumSignBits(Op.getOperand(0), Depth + 1);
6231 if (Tmp0 == 1)
6232 return 1; // Early out.
6233
6234 return std::min({Tmp0, Tmp1, Tmp2});
6235 }
6236 default:
6237 return 1;
6238 }
6239}
6240
6242 GISelValueTracking &Analysis, Register R, const APInt &DemandedElts,
6243 const MachineRegisterInfo &MRI, unsigned Depth) const {
6244 const MachineInstr *MI = MRI.getVRegDef(R);
6245 if (!MI)
6246 return 1;
6247
6248 // TODO: Check range metadata on MMO.
6249 switch (MI->getOpcode()) {
6250 case AMDGPU::G_AMDGPU_BUFFER_LOAD_SBYTE:
6251 return 25;
6252 case AMDGPU::G_AMDGPU_BUFFER_LOAD_SSHORT:
6253 return 17;
6254 case AMDGPU::G_AMDGPU_BUFFER_LOAD_UBYTE:
6255 return 24;
6256 case AMDGPU::G_AMDGPU_BUFFER_LOAD_USHORT:
6257 return 16;
6258 case AMDGPU::G_AMDGPU_SMED3:
6259 case AMDGPU::G_AMDGPU_UMED3: {
6260 auto [Dst, Src0, Src1, Src2] = MI->getFirst4Regs();
6261 unsigned Tmp2 = Analysis.computeNumSignBits(Src2, DemandedElts, Depth + 1);
6262 if (Tmp2 == 1)
6263 return 1;
6264 unsigned Tmp1 = Analysis.computeNumSignBits(Src1, DemandedElts, Depth + 1);
6265 if (Tmp1 == 1)
6266 return 1;
6267 unsigned Tmp0 = Analysis.computeNumSignBits(Src0, DemandedElts, Depth + 1);
6268 if (Tmp0 == 1)
6269 return 1;
6270 return std::min({Tmp0, Tmp1, Tmp2});
6271 }
6272 default:
6273 return 1;
6274 }
6275}
6276
6278 SDValue Op, const APInt &DemandedElts, const SelectionDAG &DAG,
6279 UndefPoisonKind Kind, bool ConsiderFlags, unsigned Depth) const {
6280 unsigned Opcode = Op.getOpcode();
6281 switch (Opcode) {
6282 case AMDGPUISD::BFE_I32:
6283 case AMDGPUISD::BFE_U32:
6284 return false;
6285 }
6287 Op, DemandedElts, DAG, Kind, ConsiderFlags, Depth);
6288}
6289
6291 SDValue Op, const APInt &DemandedElts, const SelectionDAG &DAG, bool SNaN,
6292 unsigned Depth) const {
6293 unsigned Opcode = Op.getOpcode();
6294 switch (Opcode) {
6295 case AMDGPUISD::FMIN_LEGACY:
6296 case AMDGPUISD::FMAX_LEGACY:
6297 return DAG.isKnownNeverNaN(Op.getOperand(0), SNaN, Depth + 1) &&
6298 DAG.isKnownNeverNaN(Op.getOperand(1), SNaN, Depth + 1);
6299 case AMDGPUISD::FMUL_LEGACY:
6300 case AMDGPUISD::CVT_PKRTZ_F16_F32: {
6301 if (SNaN)
6302 return true;
6303 return DAG.isKnownNeverNaN(Op.getOperand(0), SNaN, Depth + 1) &&
6304 DAG.isKnownNeverNaN(Op.getOperand(1), SNaN, Depth + 1);
6305 }
6306 case AMDGPUISD::FMED3:
6307 case AMDGPUISD::FMIN3:
6308 case AMDGPUISD::FMAX3:
6309 case AMDGPUISD::FMINIMUM3:
6310 case AMDGPUISD::FMAXIMUM3:
6311 case AMDGPUISD::FMAD_FTZ: {
6312 if (SNaN)
6313 return true;
6314 return DAG.isKnownNeverNaN(Op.getOperand(0), SNaN, Depth + 1) &&
6315 DAG.isKnownNeverNaN(Op.getOperand(1), SNaN, Depth + 1) &&
6316 DAG.isKnownNeverNaN(Op.getOperand(2), SNaN, Depth + 1);
6317 }
6318 case AMDGPUISD::CVT_F32_UBYTE0:
6319 case AMDGPUISD::CVT_F32_UBYTE1:
6320 case AMDGPUISD::CVT_F32_UBYTE2:
6321 case AMDGPUISD::CVT_F32_UBYTE3:
6322 return true;
6323
6324 case AMDGPUISD::RCP:
6325 case AMDGPUISD::RSQ:
6326 case AMDGPUISD::RCP_LEGACY:
6327 case AMDGPUISD::RSQ_CLAMP: {
6328 if (SNaN)
6329 return true;
6330
6331 // TODO: Need is known positive check.
6332 return false;
6333 }
6334 case ISD::FLDEXP:
6335 case AMDGPUISD::FRACT: {
6336 if (SNaN)
6337 return true;
6338 return DAG.isKnownNeverNaN(Op.getOperand(0), SNaN, Depth + 1);
6339 }
6340 case AMDGPUISD::DIV_SCALE:
6341 case AMDGPUISD::DIV_FMAS:
6342 case AMDGPUISD::DIV_FIXUP:
6343 // TODO: Refine on operands.
6344 return SNaN;
6345 case AMDGPUISD::SIN_HW:
6346 case AMDGPUISD::COS_HW: {
6347 // TODO: Need check for infinity
6348 return SNaN;
6349 }
6351 unsigned IntrinsicID = Op.getConstantOperandVal(0);
6352 // TODO: Handle more intrinsics
6353 switch (IntrinsicID) {
6354 case Intrinsic::amdgcn_cubeid:
6355 case Intrinsic::amdgcn_cvt_off_f32_i4:
6356 return true;
6357
6358 case Intrinsic::amdgcn_frexp_mant: {
6359 if (SNaN)
6360 return true;
6361 return DAG.isKnownNeverNaN(Op.getOperand(1), SNaN, Depth + 1);
6362 }
6363 case Intrinsic::amdgcn_cvt_pkrtz: {
6364 if (SNaN)
6365 return true;
6366 return DAG.isKnownNeverNaN(Op.getOperand(1), SNaN, Depth + 1) &&
6367 DAG.isKnownNeverNaN(Op.getOperand(2), SNaN, Depth + 1);
6368 }
6369 case Intrinsic::amdgcn_rcp:
6370 case Intrinsic::amdgcn_rsq:
6371 case Intrinsic::amdgcn_rcp_legacy:
6372 case Intrinsic::amdgcn_rsq_legacy:
6373 case Intrinsic::amdgcn_rsq_clamp:
6374 case Intrinsic::amdgcn_tanh: {
6375 if (SNaN)
6376 return true;
6377
6378 // TODO: Need is known positive check.
6379 return false;
6380 }
6381 case Intrinsic::amdgcn_trig_preop:
6382 case Intrinsic::amdgcn_fdot2:
6383 // TODO: Refine on operand
6384 return SNaN;
6385 case Intrinsic::amdgcn_fma_legacy:
6386 if (SNaN)
6387 return true;
6388 return DAG.isKnownNeverNaN(Op.getOperand(1), SNaN, Depth + 1) &&
6389 DAG.isKnownNeverNaN(Op.getOperand(2), SNaN, Depth + 1) &&
6390 DAG.isKnownNeverNaN(Op.getOperand(3), SNaN, Depth + 1);
6391 default:
6392 return false;
6393 }
6394 }
6395 default:
6396 return false;
6397 }
6398}
6399
6401 Register N0, Register N1) const {
6402 return MRI.hasOneNonDBGUse(N0); // FIXME: handle regbanks
6403}
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)
unsigned 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:331
#define LLVM_READONLY
Definition Compiler.h:338
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...
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
bool isFPImmLegal(const APFloat &Imm, EVT VT, bool ForCodeSize) const override
Returns true if the target can instruction select the specified FP immediate natively.
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:360
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:356
This is an important class for using LLVM in a threaded context.
Definition LLVMContext.h:68
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.
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:339
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:319
#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:837
@ 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:797
@ 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:871
@ 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:898
@ 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:757
@ 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:806
@ SIGN_EXTEND
Conversion operators.
Definition ISDOpcodes.h:862
@ 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:814
@ 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:810
@ 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:779
@ 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 - Perform floating-point minimumNumber or maximumNumber on two values,...
@ 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:868
@ SELECT_CC
Select with condition operator - This selects between a true value and a false value (ops #2 and #3) ...
Definition ISDOpcodes.h:829
@ FMINNUM
FMINNUM/FMAXNUM - Perform floating-point minimum maximum on two values, following IEEE-754 definition...
@ 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:906
@ SMIN
[US]{MIN/MAX} - Binary minimum or maximum of signed or unsigned integers.
Definition ISDOpcodes.h:737
@ FP_EXTEND
X = FP_EXTEND(Y) - Extend a smaller FP type into a larger FP type.
Definition ISDOpcodes.h:996
@ VSELECT
Select with a vector condition (op #0) and two vector operands (ops #1 and #2), returning a vector re...
Definition ISDOpcodes.h:823
@ 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 - NaN-propagating minimum/maximum that also treat -0.0 as less than 0....
@ FP_TO_SINT
FP_TO_[US]INT - Convert a floating point value to a signed or unsigned integer.
Definition ISDOpcodes.h:944
@ AND
Bitwise operators - logical and, logical or, logical xor.
Definition ISDOpcodes.h:749
@ 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:805
@ 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:977
@ 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:963
@ TRUNCATE
TRUNCATE - Completely drop the high bits.
Definition ISDOpcodes.h:874
@ 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 - minimumnum/maximumnum that is same with FMINNUM_IEEE and FMAXNUM_IEEE besid...
@ 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
cl::opt< int > CostThreshold
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...