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