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