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