LLVM 24.0.0git
SIISelLowering.cpp
Go to the documentation of this file.
1//===-- SIISelLowering.cpp - SI DAG Lowering Implementation ---------------===//
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/// Custom DAG lowering for SI
11//
12//===----------------------------------------------------------------------===//
13
14#include "SIISelLowering.h"
15#include "AMDGPU.h"
16#include "AMDGPUInstrInfo.h"
17#include "AMDGPULaneMaskUtils.h"
18#include "AMDGPUMemoryUtils.h"
20#include "AMDGPUTargetMachine.h"
21#include "GCNSubtarget.h"
24#include "SIRegisterInfo.h"
25#include "llvm/ADT/APFloat.h"
26#include "llvm/ADT/APInt.h"
28#include "llvm/ADT/Statistic.h"
43#include "llvm/IR/IRBuilder.h"
45#include "llvm/IR/IntrinsicsAMDGPU.h"
46#include "llvm/IR/IntrinsicsR600.h"
47#include "llvm/IR/MDBuilder.h"
50#include "llvm/Support/ModRef.h"
53#include <optional>
54
55using namespace llvm;
56using namespace llvm::SDPatternMatch;
57
58#define DEBUG_TYPE "si-lower"
59
60STATISTIC(NumTailCalls, "Number of tail calls");
61
62static cl::opt<bool>
63 DisableLoopAlignment("amdgpu-disable-loop-alignment",
64 cl::desc("Do not align and prefetch loops"),
65 cl::init(false));
66
68 "amdgpu-use-divergent-register-indexing", cl::Hidden,
69 cl::desc("Use indirect register addressing for divergent indexes"),
70 cl::init(false));
71
73 return MF.getInfo<SIMachineFunctionInfo>()->getMode().getDenormalFPEnv();
74}
75
80
85
86static unsigned findFirstFreeSGPR(CCState &CCInfo) {
87 unsigned NumSGPRs = AMDGPU::SGPR_32RegClass.getNumRegs();
88 for (unsigned Reg = 0; Reg < NumSGPRs; ++Reg) {
89 if (!CCInfo.isAllocated(AMDGPU::SGPR0 + Reg)) {
90 return AMDGPU::SGPR0 + Reg;
91 }
92 }
93 llvm_unreachable("Cannot allocate sgpr");
94}
95
97 const GCNSubtarget &STI)
98 : AMDGPUTargetLowering(TM, STI, STI), Subtarget(&STI) {
99 addRegisterClass(MVT::i1, &AMDGPU::VReg_1RegClass);
100 addRegisterClass(MVT::i64, &AMDGPU::SReg_64RegClass);
101
102 addRegisterClass(MVT::i32, &AMDGPU::SReg_32RegClass);
103
104 const SIRegisterInfo *TRI = STI.getRegisterInfo();
105 const TargetRegisterClass *V32RegClass =
106 TRI->getDefaultVectorSuperClassForBitWidth(32);
107 addRegisterClass(MVT::f32, V32RegClass);
108
109 addRegisterClass(MVT::v2i32, &AMDGPU::SReg_64RegClass);
110
111 const TargetRegisterClass *V64RegClass =
112 TRI->getDefaultVectorSuperClassForBitWidth(64);
113
114 addRegisterClass(MVT::f64, V64RegClass);
115 addRegisterClass(MVT::v2f32, V64RegClass);
116 addRegisterClass(MVT::Untyped, V64RegClass);
117
118 addRegisterClass(MVT::v3i32, &AMDGPU::SGPR_96RegClass);
119 addRegisterClass(MVT::v3f32, TRI->getDefaultVectorSuperClassForBitWidth(96));
120
121 addRegisterClass(MVT::v2i64, &AMDGPU::SGPR_128RegClass);
122 addRegisterClass(MVT::v2f64, &AMDGPU::SGPR_128RegClass);
123
124 addRegisterClass(MVT::v4i32, &AMDGPU::SGPR_128RegClass);
125 addRegisterClass(MVT::v4f32, TRI->getDefaultVectorSuperClassForBitWidth(128));
126
127 addRegisterClass(MVT::v5i32, &AMDGPU::SGPR_160RegClass);
128 addRegisterClass(MVT::v5f32, TRI->getDefaultVectorSuperClassForBitWidth(160));
129
130 addRegisterClass(MVT::v6i32, &AMDGPU::SGPR_192RegClass);
131 addRegisterClass(MVT::v6f32, TRI->getDefaultVectorSuperClassForBitWidth(192));
132
133 addRegisterClass(MVT::v3i64, &AMDGPU::SGPR_192RegClass);
134 addRegisterClass(MVT::v3f64, TRI->getDefaultVectorSuperClassForBitWidth(192));
135
136 addRegisterClass(MVT::v7i32, &AMDGPU::SGPR_224RegClass);
137 addRegisterClass(MVT::v7f32, TRI->getDefaultVectorSuperClassForBitWidth(224));
138
139 addRegisterClass(MVT::v8i32, &AMDGPU::SGPR_256RegClass);
140 addRegisterClass(MVT::v8f32, TRI->getDefaultVectorSuperClassForBitWidth(256));
141
142 addRegisterClass(MVT::v4i64, &AMDGPU::SGPR_256RegClass);
143 addRegisterClass(MVT::v4f64, TRI->getDefaultVectorSuperClassForBitWidth(256));
144
145 addRegisterClass(MVT::v9i32, &AMDGPU::SGPR_288RegClass);
146 addRegisterClass(MVT::v9f32, TRI->getDefaultVectorSuperClassForBitWidth(288));
147
148 addRegisterClass(MVT::v10i32, &AMDGPU::SGPR_320RegClass);
149 addRegisterClass(MVT::v10f32,
150 TRI->getDefaultVectorSuperClassForBitWidth(320));
151
152 addRegisterClass(MVT::v11i32, &AMDGPU::SGPR_352RegClass);
153 addRegisterClass(MVT::v11f32,
154 TRI->getDefaultVectorSuperClassForBitWidth(352));
155
156 addRegisterClass(MVT::v12i32, &AMDGPU::SGPR_384RegClass);
157 addRegisterClass(MVT::v12f32,
158 TRI->getDefaultVectorSuperClassForBitWidth(384));
159
160 addRegisterClass(MVT::v16i32, &AMDGPU::SGPR_512RegClass);
161 addRegisterClass(MVT::v16f32,
162 TRI->getDefaultVectorSuperClassForBitWidth(512));
163
164 addRegisterClass(MVT::v8i64, &AMDGPU::SGPR_512RegClass);
165 addRegisterClass(MVT::v8f64, TRI->getDefaultVectorSuperClassForBitWidth(512));
166
167 addRegisterClass(MVT::v16i64, &AMDGPU::SGPR_1024RegClass);
168 addRegisterClass(MVT::v16f64,
169 TRI->getDefaultVectorSuperClassForBitWidth(1024));
170
171 if (Subtarget->has16BitInsts()) {
172 if (Subtarget->useRealTrue16Insts()) {
173 addRegisterClass(MVT::i16, &AMDGPU::VGPR_16RegClass);
174 addRegisterClass(MVT::f16, &AMDGPU::VGPR_16RegClass);
175 addRegisterClass(MVT::bf16, &AMDGPU::VGPR_16RegClass);
176 } else {
177 addRegisterClass(MVT::i16, &AMDGPU::SReg_32RegClass);
178 addRegisterClass(MVT::f16, &AMDGPU::SReg_32RegClass);
179 addRegisterClass(MVT::bf16, &AMDGPU::SReg_32RegClass);
180 }
181
182 // Unless there are also VOP3P operations, not operations are really legal.
183 addRegisterClass(MVT::v2i16, &AMDGPU::SReg_32RegClass);
184 addRegisterClass(MVT::v2f16, &AMDGPU::SReg_32RegClass);
185 addRegisterClass(MVT::v2bf16, &AMDGPU::SReg_32RegClass);
186 addRegisterClass(MVT::v4i16, &AMDGPU::SReg_64RegClass);
187 addRegisterClass(MVT::v4f16, &AMDGPU::SReg_64RegClass);
188 addRegisterClass(MVT::v4bf16, &AMDGPU::SReg_64RegClass);
189 addRegisterClass(MVT::v8i16, &AMDGPU::SGPR_128RegClass);
190 addRegisterClass(MVT::v8f16, &AMDGPU::SGPR_128RegClass);
191 addRegisterClass(MVT::v8bf16, &AMDGPU::SGPR_128RegClass);
192 addRegisterClass(MVT::v16i16, &AMDGPU::SGPR_256RegClass);
193 addRegisterClass(MVT::v16f16, &AMDGPU::SGPR_256RegClass);
194 addRegisterClass(MVT::v16bf16, &AMDGPU::SGPR_256RegClass);
195 addRegisterClass(MVT::v32i16, &AMDGPU::SGPR_512RegClass);
196 addRegisterClass(MVT::v32f16, &AMDGPU::SGPR_512RegClass);
197 addRegisterClass(MVT::v32bf16, &AMDGPU::SGPR_512RegClass);
198 }
199
200 addRegisterClass(MVT::v32i32, &AMDGPU::VReg_1024RegClass);
201 addRegisterClass(MVT::v32f32,
202 TRI->getDefaultVectorSuperClassForBitWidth(1024));
203
204 computeRegisterProperties(Subtarget->getRegisterInfo());
205
208
209 // The boolean content concept here is too inflexible. Compares only ever
210 // really produce a 1-bit result. Any copy/extend from these will turn into a
211 // select, and zext/1 or sext/-1 are equally cheap. Arbitrarily choose 0/1, as
212 // it's what most targets use.
215
216 // We need to custom lower vector stores from local memory
218 {MVT::v2i32, MVT::v3i32, MVT::v4i32, MVT::v5i32,
219 MVT::v6i32, MVT::v7i32, MVT::v8i32, MVT::v9i32,
220 MVT::v10i32, MVT::v11i32, MVT::v12i32, MVT::v16i32,
221 MVT::i1, MVT::v32i32},
222 Custom);
223
225 {MVT::v2i32, MVT::v3i32, MVT::v4i32, MVT::v5i32,
226 MVT::v6i32, MVT::v7i32, MVT::v8i32, MVT::v9i32,
227 MVT::v10i32, MVT::v11i32, MVT::v12i32, MVT::v16i32,
228 MVT::i1, MVT::v32i32},
229 Custom);
230
231 if (isTypeLegal(MVT::bf16)) {
232 for (unsigned Opc :
241 ISD::SETCC}) {
242 setOperationAction(Opc, MVT::bf16, Promote);
243 }
244
245 // Only targets with packed bf16 instructions, e.g. gfx13.
246 if (Subtarget->hasBF16PackedInsts()) {
247 // Don't use Expand for fsub - the DAG combiner will undo fadd+fneg back
248 // to fsub, causing a libcall (which doesn't exist for bf16). Instead,
249 // directly expand to widened v2bf16 operations.
251 // Promote scalar operations to a v2bf16 operation with an unused high
252 // lane.
253 for (unsigned Opc : {ISD::FADD, ISD::FMUL, ISD::FMA, ISD::FMAXNUM,
255 AddPromotedToType(Opc, MVT::bf16, MVT::v2bf16);
256 }
257
259
261 AddPromotedToType(ISD::SELECT, MVT::bf16, MVT::i16);
262
266
267 // We only need to custom lower because we can't specify an action for bf16
268 // sources.
271 }
272
273 setTruncStoreAction(MVT::v2i32, MVT::v2i16, Expand);
274 setTruncStoreAction(MVT::v3i32, MVT::v3i16, Expand);
275 setTruncStoreAction(MVT::v4i32, MVT::v4i16, Expand);
276 setTruncStoreAction(MVT::v8i32, MVT::v8i16, Expand);
277 setTruncStoreAction(MVT::v16i32, MVT::v16i16, Expand);
278 setTruncStoreAction(MVT::v32i32, MVT::v32i16, Expand);
279 setTruncStoreAction(MVT::v2i32, MVT::v2i8, Expand);
280 setTruncStoreAction(MVT::v4i32, MVT::v4i8, Expand);
281 setTruncStoreAction(MVT::v8i32, MVT::v8i8, Expand);
282 setTruncStoreAction(MVT::v16i32, MVT::v16i8, Expand);
283 setTruncStoreAction(MVT::v32i32, MVT::v32i8, Expand);
284 setTruncStoreAction(MVT::v2i16, MVT::v2i8, Expand);
285 setTruncStoreAction(MVT::v4i16, MVT::v4i8, Expand);
286 setTruncStoreAction(MVT::v8i16, MVT::v8i8, Expand);
287 setTruncStoreAction(MVT::v16i16, MVT::v16i8, Expand);
288 setTruncStoreAction(MVT::v32i16, MVT::v32i8, Expand);
289
290 setTruncStoreAction(MVT::v3i64, MVT::v3i16, Expand);
291 setTruncStoreAction(MVT::v3i64, MVT::v3i32, Expand);
292 setTruncStoreAction(MVT::v4i64, MVT::v4i8, Expand);
293 setTruncStoreAction(MVT::v8i64, MVT::v8i8, Expand);
294 setTruncStoreAction(MVT::v8i64, MVT::v8i16, Expand);
295 setTruncStoreAction(MVT::v8i64, MVT::v8i32, Expand);
296 setTruncStoreAction(MVT::v16i64, MVT::v16i32, Expand);
297
298 setOperationAction(ISD::GlobalAddress, {MVT::i32, MVT::i64}, Custom);
299 setOperationAction(ISD::BlockAddress, {MVT::i32, MVT::i64}, Custom);
300 setOperationAction(ISD::ExternalSymbol, {MVT::i32, MVT::i64}, Custom);
301
305 AddPromotedToType(ISD::SELECT, MVT::f64, MVT::i64);
306
307 setOperationAction(ISD::FSQRT, {MVT::f32, MVT::f64}, Custom);
308
310 {MVT::f32, MVT::i32, MVT::i64, MVT::f64, MVT::i1}, Expand);
311
313 setOperationAction(ISD::SETCC, {MVT::v2i1, MVT::v4i1}, Expand);
314 AddPromotedToType(ISD::SETCC, MVT::i1, MVT::i32);
315
317 {MVT::v2i32, MVT::v3i32, MVT::v4i32, MVT::v5i32,
318 MVT::v6i32, MVT::v7i32, MVT::v8i32, MVT::v9i32,
319 MVT::v10i32, MVT::v11i32, MVT::v12i32, MVT::v16i32},
320 Expand);
322 {MVT::v2f32, MVT::v3f32, MVT::v4f32, MVT::v5f32,
323 MVT::v6f32, MVT::v7f32, MVT::v8f32, MVT::v9f32,
324 MVT::v10f32, MVT::v11f32, MVT::v12f32, MVT::v16f32},
325 Expand);
326
328 {MVT::v2i1, MVT::v4i1, MVT::v2i8, MVT::v4i8, MVT::v2i16,
329 MVT::v3i16, MVT::v4i16, MVT::Other},
330 Custom);
331
334 {MVT::i1, MVT::i32, MVT::i64, MVT::f32, MVT::f64}, Expand);
335
338
341
343 Expand);
344
346
347 // We only support LOAD/STORE and vector manipulation ops for vectors
348 // with > 4 elements.
349 for (MVT VT :
350 {MVT::v8i32, MVT::v8f32, MVT::v9i32, MVT::v9f32, MVT::v10i32,
351 MVT::v10f32, MVT::v11i32, MVT::v11f32, MVT::v12i32, MVT::v12f32,
352 MVT::v16i32, MVT::v16f32, MVT::v2i64, MVT::v2f64, MVT::v4i16,
353 MVT::v4f16, MVT::v4bf16, MVT::v3i64, MVT::v3f64, MVT::v6i32,
354 MVT::v6f32, MVT::v4i64, MVT::v4f64, MVT::v8i64, MVT::v8f64,
355 MVT::v8i16, MVT::v8f16, MVT::v8bf16, MVT::v16i16, MVT::v16f16,
356 MVT::v16bf16, MVT::v16i64, MVT::v16f64, MVT::v32i32, MVT::v32f32,
357 MVT::v32i16, MVT::v32f16, MVT::v32bf16}) {
358 for (unsigned Op = 0; Op < ISD::BUILTIN_OP_END; ++Op) {
359 switch (Op) {
360 case ISD::LOAD:
361 case ISD::STORE:
363 case ISD::BITCAST:
364 case ISD::UNDEF:
365 case ISD::POISON:
369 case ISD::IS_FPCLASS:
370 break;
375 break;
376 default:
378 break;
379 }
380 }
381 }
382
384
385 // TODO: For dynamic 64-bit vector inserts/extracts, should emit a pseudo that
386 // is expanded to avoid having two separate loops in case the index is a VGPR.
387
388 // Most operations are naturally 32-bit vector operations. We only support
389 // load and store of i64 vectors, so promote v2i64 vector operations to v4i32.
390 for (MVT Vec64 : {MVT::v2i64, MVT::v2f64}) {
392 AddPromotedToType(ISD::BUILD_VECTOR, Vec64, MVT::v4i32);
393
395 AddPromotedToType(ISD::EXTRACT_VECTOR_ELT, Vec64, MVT::v4i32);
396
398 AddPromotedToType(ISD::INSERT_VECTOR_ELT, Vec64, MVT::v4i32);
399
401 AddPromotedToType(ISD::SCALAR_TO_VECTOR, Vec64, MVT::v4i32);
402 }
403
404 for (MVT Vec64 : {MVT::v3i64, MVT::v3f64}) {
406 AddPromotedToType(ISD::BUILD_VECTOR, Vec64, MVT::v6i32);
407
409 AddPromotedToType(ISD::EXTRACT_VECTOR_ELT, Vec64, MVT::v6i32);
410
412 AddPromotedToType(ISD::INSERT_VECTOR_ELT, Vec64, MVT::v6i32);
413
415 AddPromotedToType(ISD::SCALAR_TO_VECTOR, Vec64, MVT::v6i32);
416 }
417
418 for (MVT Vec64 : {MVT::v4i64, MVT::v4f64}) {
420 AddPromotedToType(ISD::BUILD_VECTOR, Vec64, MVT::v8i32);
421
423 AddPromotedToType(ISD::EXTRACT_VECTOR_ELT, Vec64, MVT::v8i32);
424
426 AddPromotedToType(ISD::INSERT_VECTOR_ELT, Vec64, MVT::v8i32);
427
429 AddPromotedToType(ISD::SCALAR_TO_VECTOR, Vec64, MVT::v8i32);
430 }
431
432 for (MVT Vec64 : {MVT::v8i64, MVT::v8f64}) {
434 AddPromotedToType(ISD::BUILD_VECTOR, Vec64, MVT::v16i32);
435
437 AddPromotedToType(ISD::EXTRACT_VECTOR_ELT, Vec64, MVT::v16i32);
438
440 AddPromotedToType(ISD::INSERT_VECTOR_ELT, Vec64, MVT::v16i32);
441
443 AddPromotedToType(ISD::SCALAR_TO_VECTOR, Vec64, MVT::v16i32);
444 }
445
446 for (MVT Vec64 : {MVT::v16i64, MVT::v16f64}) {
448 AddPromotedToType(ISD::BUILD_VECTOR, Vec64, MVT::v32i32);
449
451 AddPromotedToType(ISD::EXTRACT_VECTOR_ELT, Vec64, MVT::v32i32);
452
454 AddPromotedToType(ISD::INSERT_VECTOR_ELT, Vec64, MVT::v32i32);
455
457 AddPromotedToType(ISD::SCALAR_TO_VECTOR, Vec64, MVT::v32i32);
458 }
459
461 {MVT::v4i32, MVT::v4f32, MVT::v8i32, MVT::v8f32,
462 MVT::v16i32, MVT::v16f32, MVT::v32i32, MVT::v32f32},
463 Custom);
464
465 if (Subtarget->hasPkMovB32()) {
466 // TODO: 16-bit element vectors should be legal with even aligned elements.
467 // TODO: Can be legal with wider source types than the result with
468 // subregister extracts.
469 setOperationAction(ISD::VECTOR_SHUFFLE, {MVT::v2i32, MVT::v2f32}, Legal);
470 }
471
473 // Prevent SELECT v2i32 from being implemented with the above bitwise ops and
474 // instead lower to cndmask in SITargetLowering::LowerSELECT().
476 // Enable MatchRotate to produce ISD::ROTR, which is later transformed to
477 // alignbit.
478 setOperationAction(ISD::ROTR, MVT::v2i32, Custom);
479
480 setOperationAction(ISD::BUILD_VECTOR, {MVT::v4f16, MVT::v4i16, MVT::v4bf16},
481 Custom);
482
483 // Avoid stack access for these.
484 // TODO: Generalize to more vector types.
486 {MVT::v2i16, MVT::v2f16, MVT::v2bf16, MVT::v2i8, MVT::v4i8,
487 MVT::v8i8, MVT::v4i16, MVT::v4f16, MVT::v4bf16},
488 Custom);
489
490 // Deal with vec3 vector operations when widened to vec4.
492 {MVT::v3i32, MVT::v3f32, MVT::v4i32, MVT::v4f32}, Custom);
493
494 // Deal with vec5/6/7 vector operations when widened to vec8.
496 {MVT::v5i32, MVT::v5f32, MVT::v6i32, MVT::v6f32,
497 MVT::v7i32, MVT::v7f32, MVT::v8i32, MVT::v8f32,
498 MVT::v9i32, MVT::v9f32, MVT::v10i32, MVT::v10f32,
499 MVT::v11i32, MVT::v11f32, MVT::v12i32, MVT::v12f32},
500 Custom);
501
502 // BUFFER/FLAT_ATOMIC_CMP_SWAP on GCN GPUs needs input marshalling,
503 // and output demarshalling
504 setOperationAction(ISD::ATOMIC_CMP_SWAP, {MVT::i32, MVT::i64}, Custom);
505
506 // We can't return success/failure, only the old value,
507 // let LLVM add the comparison
509 Expand);
510
511 setOperationAction(ISD::ADDRSPACECAST, {MVT::i32, MVT::i64}, Custom);
512
513 setOperationAction(ISD::BITREVERSE, {MVT::i32, MVT::i64}, Legal);
514
515 // FIXME: This should be narrowed to i32, but that only happens if i64 is
516 // illegal.
517 // FIXME: Should lower sub-i32 bswaps to bit-ops without v_perm_b32.
518 setOperationAction(ISD::BSWAP, {MVT::i64, MVT::i32}, Legal);
519
520 // On SI this is s_memtime and s_memrealtime on VI.
522
523 if (Subtarget->hasSMemRealTime() ||
524 Subtarget->getGeneration() >= AMDGPUSubtarget::GFX11)
527
528 if (Subtarget->has16BitInsts()) {
531 setOperationAction(ISD::IS_FPCLASS, {MVT::f16, MVT::f32, MVT::f64}, Legal);
534 } else {
536 }
537
538 if (Subtarget->hasMadMacF32Insts())
540
544
545 // We only really have 32-bit BFE instructions (and 16-bit on VI).
546 //
547 // On SI+ there are 64-bit BFEs, but they are scalar only and there isn't any
548 // effort to match them now. We want this to be false for i64 cases when the
549 // extraction isn't restricted to the upper or lower half. Ideally we would
550 // have some pass reduce 64-bit extracts to 32-bit if possible. Extracts that
551 // span the midpoint are probably relatively rare, so don't worry about them
552 // for now.
554
555 // Clamp modifier on add/sub
556 if (Subtarget->hasIntClamp())
558
559 if (Subtarget->hasAddNoCarryInsts())
560 setOperationAction({ISD::SADDSAT, ISD::SSUBSAT}, {MVT::i16, MVT::i32},
561 Legal);
562
565 {MVT::f32, MVT::f64}, Custom);
566
567 // These are really only legal for ieee_mode functions. We should be avoiding
568 // them for functions that don't have ieee_mode enabled, so just say they are
569 // legal.
571 {MVT::f32, MVT::f64}, Legal);
572
573 if (Subtarget->haveRoundOpsF64())
575 Legal);
576 else
578 MVT::f64, Custom);
579
581 setOperationAction({ISD::FLDEXP, ISD::STRICT_FLDEXP}, {MVT::f32, MVT::f64},
582 Legal);
583 setOperationAction(ISD::FFREXP, {MVT::f32, MVT::f64}, Custom);
584
587
588 setOperationAction(ISD::BF16_TO_FP, {MVT::i16, MVT::f32, MVT::f64}, Expand);
589 setOperationAction(ISD::FP_TO_BF16, {MVT::i16, MVT::f32, MVT::f64}, Expand);
590
592 Custom);
594 Custom);
596 Custom);
597
598 // Custom lower these because we can't specify a rule based on an illegal
599 // source bf16.
602
603 if (Subtarget->has16BitInsts()) {
606 MVT::i16, Legal);
607
608 AddPromotedToType(ISD::SIGN_EXTEND, MVT::i16, MVT::i32);
609
611 MVT::i16, Expand);
612
616 ISD::CTPOP},
617 MVT::i16, Promote);
618
620
621 setTruncStoreAction(MVT::i64, MVT::i16, Expand);
622
624 AddPromotedToType(ISD::FP16_TO_FP, MVT::i16, MVT::i32);
626 AddPromotedToType(ISD::FP_TO_FP16, MVT::i16, MVT::i32);
627
632
634
635 // F16 - Constant Actions.
638
639 // F16 - Load/Store Actions.
641 AddPromotedToType(ISD::LOAD, MVT::f16, MVT::i16);
643 AddPromotedToType(ISD::STORE, MVT::f16, MVT::i16);
644
645 // BF16 - Load/Store Actions.
647 AddPromotedToType(ISD::LOAD, MVT::bf16, MVT::i16);
649 AddPromotedToType(ISD::STORE, MVT::bf16, MVT::i16);
650
651 // F16 - VOP1 Actions.
654 MVT::f16, Custom);
655
656 // BF16 - VOP1 Actions.
657 if (Subtarget->hasBF16TransInsts())
659
660 // F16 - VOP2 Actions.
661 setOperationAction({ISD::BR_CC, ISD::SELECT_CC}, {MVT::f16, MVT::bf16},
662 Expand);
666
667 // F16 - VOP3 Actions.
669 if (STI.hasMadF16())
671
672 for (MVT VT :
673 {MVT::v2i16, MVT::v2f16, MVT::v2bf16, MVT::v4i16, MVT::v4f16,
674 MVT::v4bf16, MVT::v8i16, MVT::v8f16, MVT::v8bf16, MVT::v16i16,
675 MVT::v16f16, MVT::v16bf16, MVT::v32i16, MVT::v32f16}) {
676 for (unsigned Op = 0; Op < ISD::BUILTIN_OP_END; ++Op) {
677 switch (Op) {
678 case ISD::LOAD:
679 case ISD::STORE:
681 case ISD::BITCAST:
682 case ISD::UNDEF:
683 case ISD::POISON:
688 case ISD::IS_FPCLASS:
689 break;
692 case ISD::FSIN:
693 case ISD::FCOS:
695 break;
696 default:
698 break;
699 }
700 }
701 }
702
703 // v_perm_b32 can handle either of these.
704 setOperationAction(ISD::BSWAP, {MVT::i16, MVT::v2i16}, Legal);
706
707 // Legalize vector types for sat conversions to select v_cvt_pk_[iu]16_f32.
708 if (Subtarget->hasVCvtPkIU16F32())
711 {MVT::v2i16, MVT::v4i16, MVT::v8i16, MVT::v16i16, MVT::v32i16},
712 Custom);
713
714 // XXX - Do these do anything? Vector constants turn into build_vector.
715 setOperationAction(ISD::Constant, {MVT::v2i16, MVT::v2f16}, Legal);
716
718 {MVT::v2i16, MVT::v2f16, MVT::v2bf16}, Legal);
719
721 AddPromotedToType(ISD::STORE, MVT::v2i16, MVT::i32);
723 AddPromotedToType(ISD::STORE, MVT::v2f16, MVT::i32);
724
726 AddPromotedToType(ISD::LOAD, MVT::v2i16, MVT::i32);
728 AddPromotedToType(ISD::LOAD, MVT::v2f16, MVT::i32);
729
731 AddPromotedToType(ISD::ATOMIC_LOAD, MVT::v2i16, MVT::i32);
733 AddPromotedToType(ISD::ATOMIC_LOAD, MVT::v2f16, MVT::i32);
734
736 AddPromotedToType(ISD::ATOMIC_STORE, MVT::v2i16, MVT::i32);
738 AddPromotedToType(ISD::ATOMIC_STORE, MVT::v2f16, MVT::i32);
739
740 setOperationAction(ISD::AND, MVT::v2i16, Promote);
741 AddPromotedToType(ISD::AND, MVT::v2i16, MVT::i32);
742 setOperationAction(ISD::OR, MVT::v2i16, Promote);
743 AddPromotedToType(ISD::OR, MVT::v2i16, MVT::i32);
744 setOperationAction(ISD::XOR, MVT::v2i16, Promote);
745 AddPromotedToType(ISD::XOR, MVT::v2i16, MVT::i32);
746
748 AddPromotedToType(ISD::LOAD, MVT::v4i16, MVT::v2i32);
750 AddPromotedToType(ISD::LOAD, MVT::v4f16, MVT::v2i32);
751 setOperationAction(ISD::LOAD, MVT::v4bf16, Promote);
752 AddPromotedToType(ISD::LOAD, MVT::v4bf16, MVT::v2i32);
753
755 AddPromotedToType(ISD::ATOMIC_LOAD, MVT::v4i16, MVT::i64);
757 AddPromotedToType(ISD::ATOMIC_LOAD, MVT::v4f16, MVT::i64);
758
760 AddPromotedToType(ISD::ATOMIC_STORE, MVT::v4i16, MVT::i64);
762 AddPromotedToType(ISD::ATOMIC_STORE, MVT::v4f16, MVT::i64);
763
765 AddPromotedToType(ISD::STORE, MVT::v4i16, MVT::v2i32);
767 AddPromotedToType(ISD::STORE, MVT::v4f16, MVT::v2i32);
769 AddPromotedToType(ISD::STORE, MVT::v4bf16, MVT::v2i32);
770
772 AddPromotedToType(ISD::LOAD, MVT::v8i16, MVT::v4i32);
774 AddPromotedToType(ISD::LOAD, MVT::v8f16, MVT::v4i32);
775 setOperationAction(ISD::LOAD, MVT::v8bf16, Promote);
776 AddPromotedToType(ISD::LOAD, MVT::v8bf16, MVT::v4i32);
777
779 AddPromotedToType(ISD::STORE, MVT::v4i16, MVT::v2i32);
781 AddPromotedToType(ISD::STORE, MVT::v4f16, MVT::v2i32);
782
784 AddPromotedToType(ISD::STORE, MVT::v8i16, MVT::v4i32);
786 AddPromotedToType(ISD::STORE, MVT::v8f16, MVT::v4i32);
788 AddPromotedToType(ISD::STORE, MVT::v8bf16, MVT::v4i32);
789
790 setOperationAction(ISD::LOAD, MVT::v16i16, Promote);
791 AddPromotedToType(ISD::LOAD, MVT::v16i16, MVT::v8i32);
792 setOperationAction(ISD::LOAD, MVT::v16f16, Promote);
793 AddPromotedToType(ISD::LOAD, MVT::v16f16, MVT::v8i32);
794 setOperationAction(ISD::LOAD, MVT::v16bf16, Promote);
795 AddPromotedToType(ISD::LOAD, MVT::v16bf16, MVT::v8i32);
796
798 AddPromotedToType(ISD::STORE, MVT::v16i16, MVT::v8i32);
800 AddPromotedToType(ISD::STORE, MVT::v16f16, MVT::v8i32);
801 setOperationAction(ISD::STORE, MVT::v16bf16, Promote);
802 AddPromotedToType(ISD::STORE, MVT::v16bf16, MVT::v8i32);
803
804 setOperationAction(ISD::LOAD, MVT::v32i16, Promote);
805 AddPromotedToType(ISD::LOAD, MVT::v32i16, MVT::v16i32);
806 setOperationAction(ISD::LOAD, MVT::v32f16, Promote);
807 AddPromotedToType(ISD::LOAD, MVT::v32f16, MVT::v16i32);
808 setOperationAction(ISD::LOAD, MVT::v32bf16, Promote);
809 AddPromotedToType(ISD::LOAD, MVT::v32bf16, MVT::v16i32);
810
812 AddPromotedToType(ISD::STORE, MVT::v32i16, MVT::v16i32);
814 AddPromotedToType(ISD::STORE, MVT::v32f16, MVT::v16i32);
815 setOperationAction(ISD::STORE, MVT::v32bf16, Promote);
816 AddPromotedToType(ISD::STORE, MVT::v32bf16, MVT::v16i32);
817
819 MVT::v2i32, Expand);
821
823 MVT::v4i32, Expand);
824
826 MVT::v8i32, Expand);
827
828 setOperationAction(ISD::BUILD_VECTOR, {MVT::v2i16, MVT::v2f16, MVT::v2bf16},
829 Subtarget->hasVOP3PInsts() ? Legal : Custom);
830
831 setOperationAction(ISD::FNEG, {MVT::v2f16, MVT::v2bf16}, Legal);
832 // This isn't really legal, but this avoids the legalizer unrolling it (and
833 // allows matching fneg (fabs x) patterns)
834 setOperationAction(ISD::FABS, {MVT::v2f16, MVT::v2bf16}, Legal);
835
836 // Can do this in one BFI plus a constant materialize.
838 {MVT::v2f16, MVT::v2bf16, MVT::v4f16, MVT::v4bf16,
839 MVT::v8f16, MVT::v8bf16, MVT::v16f16, MVT::v16bf16,
840 MVT::v32f16, MVT::v32bf16},
841 Custom);
842
845 MVT::f16, Custom);
847
850 {MVT::v4f16, MVT::v8f16, MVT::v16f16, MVT::v32f16},
851 Custom);
852
854 {MVT::v4f16, MVT::v8f16, MVT::v16f16, MVT::v32f16},
855 Expand);
856
857 for (MVT Vec16 :
858 {MVT::v8i16, MVT::v8f16, MVT::v8bf16, MVT::v16i16, MVT::v16f16,
859 MVT::v16bf16, MVT::v32i16, MVT::v32f16, MVT::v32bf16}) {
862 Vec16, Custom);
864 }
865 }
866
867 if (Subtarget->hasVOP3PInsts()) {
871 MVT::v2i16, Legal);
872
876 MVT::v2f16, Legal);
877
879 {MVT::v2i16, MVT::v2f16, MVT::v2bf16}, Custom);
880
882 {MVT::v4f16, MVT::v4i16, MVT::v4bf16, MVT::v8f16,
883 MVT::v8i16, MVT::v8bf16, MVT::v16f16, MVT::v16i16,
884 MVT::v16bf16, MVT::v32f16, MVT::v32i16, MVT::v32bf16},
885 Custom);
886
887 for (MVT VT : {MVT::v4i16, MVT::v8i16, MVT::v16i16, MVT::v32i16})
888 // Split vector operations.
893 VT, Custom);
894
895 for (MVT VT : {MVT::v4f16, MVT::v8f16, MVT::v16f16, MVT::v32f16})
896 // Split vector operations.
899 VT, Custom);
900
903 {MVT::v2f16, MVT::v4f16}, Custom);
904
905 setOperationAction(ISD::FEXP, MVT::v2f16, Custom);
906 setOperationAction(ISD::SELECT, {MVT::v4i16, MVT::v4f16, MVT::v4bf16},
907 Custom);
908
909 if (Subtarget->hasBF16PackedInsts()) {
912 MVT::v2bf16, Legal);
913
914 for (MVT VT : {MVT::v4bf16, MVT::v8bf16, MVT::v16bf16, MVT::v32bf16})
915 // Split vector operations.
918 VT, Custom);
919 }
920
921 if (Subtarget->hasAnyPackedFP32Ops()) {
923 MVT::v2f32, Legal);
925 {MVT::v4f32, MVT::v8f32, MVT::v16f32, MVT::v32f32},
926 Custom);
927 }
928 if (Subtarget->hasAnyPackedFP64Ops()) {
932 MVT::v2f64, Legal);
935 MVT::v2f64, Custom);
940 {MVT::v4f64, MVT::v8f64, MVT::v16f64, MVT::v32f64}, Custom);
941 }
942
943 if (Subtarget->hasAnyPackedU64Ops()) {
945 MVT::v2i64, Legal);
947 {MVT::v4i64, MVT::v8i64, MVT::v16i64, MVT::v32i64},
948 Custom);
949 }
950 }
951
953
954 if (Subtarget->has16BitInsts()) {
956 AddPromotedToType(ISD::SELECT, MVT::v2i16, MVT::i32);
958 AddPromotedToType(ISD::SELECT, MVT::v2f16, MVT::i32);
960 AddPromotedToType(ISD::SELECT, MVT::v2bf16, MVT::i32);
961 } else {
962 // Legalization hack.
963 setOperationAction(ISD::SELECT, {MVT::v2i16, MVT::v2f16}, Custom);
964
966 }
967
969 {MVT::v4i16, MVT::v4f16, MVT::v4bf16, MVT::v2i8, MVT::v4i8,
970 MVT::v8i8, MVT::v8i16, MVT::v8f16, MVT::v8bf16,
971 MVT::v16i16, MVT::v16f16, MVT::v16bf16, MVT::v32i16,
972 MVT::v32f16, MVT::v32bf16},
973 Custom);
974
976
977 if (Subtarget->hasVMulU64Inst())
979 else if (Subtarget->hasScalarSMulU64())
981
982 if (Subtarget->hasMad64_32())
984
985 if (Subtarget->hasSafeSmemPrefetch() || Subtarget->hasVmemPrefInsts())
987
988 if (Subtarget->hasIEEEMinimumMaximumInsts()) {
990 {MVT::f16, MVT::f32, MVT::f64, MVT::v2f16}, Legal);
991 } else {
992 // FIXME: For nnan fmaximum, emit the fmaximum3 instead of fmaxnum
993 if (Subtarget->hasMinimum3Maximum3F32())
995
996 if (Subtarget->hasMinimum3Maximum3PKF16()) {
998
999 // If only the vector form is available, we need to widen to a vector.
1000 if (!Subtarget->hasMinimum3Maximum3F16())
1002 MVT::v2f16);
1003 }
1004 }
1005
1006 if (Subtarget->hasVOP3PInsts()) {
1007 // We want to break these into v2f16 pieces, not scalarize.
1009 {MVT::v4f16, MVT::v8f16, MVT::v16f16, MVT::v32f16},
1010 Custom);
1011 }
1012
1013 if (Subtarget->hasMinMaxI64Insts())
1015 Legal);
1016
1018 {MVT::Other, MVT::f32, MVT::v4f32, MVT::i16, MVT::f16,
1019 MVT::bf16, MVT::v2i16, MVT::v2f16, MVT::v2bf16, MVT::i128,
1020 MVT::i8},
1021 Custom);
1022
1024 {MVT::v2f16, MVT::v2i16, MVT::v2bf16, MVT::v3f16,
1025 MVT::v3i16, MVT::v4f16, MVT::v4i16, MVT::v4bf16,
1026 MVT::v8i16, MVT::v8f16, MVT::v8bf16, MVT::Other, MVT::f16,
1027 MVT::i16, MVT::bf16, MVT::i8, MVT::i128},
1028 Custom);
1029
1031 {MVT::Other, MVT::v2i16, MVT::v2f16, MVT::v2bf16,
1032 MVT::v3i16, MVT::v3f16, MVT::v4f16, MVT::v4i16,
1033 MVT::v4bf16, MVT::v8i16, MVT::v8f16, MVT::v8bf16,
1034 MVT::f16, MVT::i16, MVT::bf16, MVT::i8, MVT::i128},
1035 Custom);
1036
1042
1043 // TODO: Could move this to custom lowering, could benefit from combines on
1044 // extract of relevant bits.
1046
1048
1049 if (Subtarget->hasBF16ConversionInsts()) {
1051 {MVT::bf16, MVT::v2bf16}, Custom);
1053 }
1054
1055 if (Subtarget->hasBF16TransInsts()) {
1057 }
1058
1059 const bool HasE5M3ConversionInsts =
1060 Subtarget->hasFP8ConversionInsts() && Subtarget->hasFP8E5M3Insts();
1061 if (Subtarget->hasOCPFP8ConversionInsts() || HasE5M3ConversionInsts) {
1062 setOperationAction(ISD::CONVERT_FROM_ARBITRARY_FP, {MVT::f32, MVT::v2f32},
1063 Custom);
1065
1066 // i8 result promotes to i16, wider vectors split down to v2i8, and v2i8 is
1067 // handled in ReplaceNodeResults before the legalizer splits it per lane.
1068 setOperationAction(ISD::CONVERT_TO_ARBITRARY_FP, {MVT::i16, MVT::v2i8},
1069 Custom);
1070 }
1071
1072 if (Subtarget->hasFP8F16ConversionInsts()) {
1073 setOperationAction(ISD::CONVERT_FROM_ARBITRARY_FP, {MVT::f16, MVT::v2f16},
1074 Custom);
1075 }
1076
1077 if (Subtarget->hasCvtPkF16F32Inst()) {
1079 {MVT::v2f16, MVT::v4f16, MVT::v8f16, MVT::v16f16},
1080 Custom);
1081 }
1082
1085 ISD::SUB,
1086 ISD::MUL,
1087 ISD::FADD,
1088 ISD::FSUB,
1089 ISD::FDIV,
1090 ISD::FMUL,
1099 ISD::FMA,
1100 ISD::ABS,
1101 ISD::SMIN,
1102 ISD::SMAX,
1103 ISD::UMIN,
1104 ISD::UMAX,
1105 ISD::SETCC,
1107 ISD::SMIN,
1108 ISD::SMAX,
1109 ISD::UMIN,
1110 ISD::UMAX,
1112 ISD::AND,
1113 ISD::OR,
1114 ISD::XOR,
1115 ISD::SHL,
1116 ISD::SRL,
1117 ISD::SRA,
1118 ISD::FSHR,
1129
1130 if (Subtarget->has16BitInsts() && !Subtarget->hasMed3_16())
1132
1133 // All memory operations. Some folding on the pointer operand is done to help
1134 // matching the constant offsets in the addressing modes.
1136 ISD::STORE,
1161
1162 // FIXME: In other contexts we pretend this is a per-function property.
1164
1166}
1167
1168const GCNSubtarget *SITargetLowering::getSubtarget() const { return Subtarget; }
1169
1171 static const MCPhysReg RCRegs[] = {AMDGPU::MODE};
1172 return RCRegs;
1173}
1174
1175//===----------------------------------------------------------------------===//
1176// TargetLowering queries
1177//===----------------------------------------------------------------------===//
1178
1179// v_mad_mix* support a conversion from f16 to f32.
1180//
1181// There is only one special case when denormals are enabled we don't currently,
1182// where this is OK to use.
1183bool SITargetLowering::isFPExtFoldable(const SelectionDAG &DAG, unsigned Opcode,
1184 EVT DestVT, EVT SrcVT) const {
1185 return DestVT.getScalarType() == MVT::f32 &&
1186 ((((Opcode == ISD::FMAD && Subtarget->hasMadMixInsts()) ||
1187 (Opcode == ISD::FMA && Subtarget->hasFmaMixInsts())) &&
1188 SrcVT.getScalarType() == MVT::f16) ||
1189 (Opcode == ISD::FMA && Subtarget->hasFmaMixBF16Insts() &&
1190 SrcVT.getScalarType() == MVT::bf16)) &&
1191 // TODO: This probably only requires no input flushing?
1193}
1194
1196 LLT DestTy, LLT SrcTy) const {
1197 return ((Opcode == TargetOpcode::G_FMAD && Subtarget->hasMadMixInsts()) ||
1198 (Opcode == TargetOpcode::G_FMA && Subtarget->hasFmaMixInsts())) &&
1199 DestTy.getScalarSizeInBits() == 32 &&
1200 SrcTy.getScalarSizeInBits() == 16 &&
1201 // TODO: This probably only requires no input flushing?
1202 denormalModeIsFlushAllF32(*MI.getMF());
1203}
1204
1206 // SI has some legal vector types, but no legal vector operations. Say no
1207 // shuffles are legal in order to prefer scalarizing some vector operations.
1208 return false;
1209}
1210
1212 CallingConv::ID CC,
1213 EVT VT) const {
1215 return TargetLowering::getRegisterTypeForCallingConv(Context, CC, VT);
1216
1217 if (VT.isVector()) {
1218 EVT ScalarVT = VT.getScalarType();
1219 unsigned Size = ScalarVT.getSizeInBits();
1220 if (Size == 16) {
1221 return Subtarget->has16BitInsts()
1222 ? MVT::getVectorVT(ScalarVT.getSimpleVT(), 2)
1223 : MVT::i32;
1224 }
1225
1226 if (Size < 16)
1227 return Subtarget->has16BitInsts() ? MVT::i16 : MVT::i32;
1228 return Size == 32 ? ScalarVT.getSimpleVT() : MVT::i32;
1229 }
1230
1231 if (!Subtarget->has16BitInsts() && VT.getSizeInBits() == 16)
1232 return MVT::i32;
1233
1234 if (VT.getSizeInBits() > 32)
1235 return MVT::i32;
1236
1237 return TargetLowering::getRegisterTypeForCallingConv(Context, CC, VT);
1238}
1239
1241 CallingConv::ID CC,
1242 EVT VT) const {
1244 return TargetLowering::getNumRegistersForCallingConv(Context, CC, VT);
1245
1246 if (VT.isVector()) {
1247 unsigned NumElts = VT.getVectorNumElements();
1248 EVT ScalarVT = VT.getScalarType();
1249 unsigned Size = ScalarVT.getSizeInBits();
1250
1251 // FIXME: Should probably promote 8-bit vectors to i16.
1252 if (Size == 16)
1253 return (NumElts + 1) / 2;
1254
1255 if (Size <= 32)
1256 return NumElts;
1257
1258 if (Size > 32)
1259 return NumElts * ((Size + 31) / 32);
1260 } else if (VT.getSizeInBits() > 32)
1261 return (VT.getSizeInBits() + 31) / 32;
1262
1263 return TargetLowering::getNumRegistersForCallingConv(Context, CC, VT);
1264}
1265
1267 LLVMContext &Context, CallingConv::ID CC, EVT VT, EVT &IntermediateVT,
1268 unsigned &NumIntermediates, MVT &RegisterVT) const {
1269 if (CC != CallingConv::AMDGPU_KERNEL && VT.isVector()) {
1270 unsigned NumElts = VT.getVectorNumElements();
1271 EVT ScalarVT = VT.getScalarType();
1272 unsigned Size = ScalarVT.getSizeInBits();
1273 // FIXME: We should fix the ABI to be the same on targets without 16-bit
1274 // support, but unless we can properly handle 3-vectors, it will be still be
1275 // inconsistent.
1276 if (Size == 16) {
1277 MVT SimpleIntermediateVT =
1279 IntermediateVT = SimpleIntermediateVT;
1280 RegisterVT = Subtarget->has16BitInsts() ? SimpleIntermediateVT : MVT::i32;
1281 NumIntermediates = (NumElts + 1) / 2;
1282 return (NumElts + 1) / 2;
1283 }
1284
1285 if (Size == 32) {
1286 RegisterVT = ScalarVT.getSimpleVT();
1287 IntermediateVT = RegisterVT;
1288 NumIntermediates = NumElts;
1289 return NumIntermediates;
1290 }
1291
1292 if (Size < 16 && Subtarget->has16BitInsts()) {
1293 // FIXME: Should probably form v2i16 pieces
1294 RegisterVT = MVT::i16;
1295 IntermediateVT = ScalarVT;
1296 NumIntermediates = NumElts;
1297 return NumIntermediates;
1298 }
1299
1300 if (Size != 16 && Size <= 32) {
1301 RegisterVT = MVT::i32;
1302 IntermediateVT = ScalarVT;
1303 NumIntermediates = NumElts;
1304 return NumIntermediates;
1305 }
1306
1307 if (Size > 32) {
1308 RegisterVT = MVT::i32;
1309 IntermediateVT = RegisterVT;
1310 NumIntermediates = NumElts * ((Size + 31) / 32);
1311 return NumIntermediates;
1312 }
1313 }
1314
1316 Context, CC, VT, IntermediateVT, NumIntermediates, RegisterVT);
1317}
1318
1320 const DataLayout &DL, Type *Ty,
1321 unsigned MaxNumLanes) {
1322 assert(MaxNumLanes != 0);
1323
1324 LLVMContext &Ctx = Ty->getContext();
1325 if (auto *VT = dyn_cast<FixedVectorType>(Ty)) {
1326 unsigned NumElts = std::min(MaxNumLanes, VT->getNumElements());
1327 return EVT::getVectorVT(Ctx, TLI.getValueType(DL, VT->getElementType()),
1328 NumElts);
1329 }
1330
1331 return TLI.getValueType(DL, Ty);
1332}
1333
1334// Peek through TFE struct returns to only use the data size.
1336 const DataLayout &DL, Type *Ty,
1337 unsigned MaxNumLanes) {
1338 auto *ST = dyn_cast<StructType>(Ty);
1339 if (!ST)
1340 return memVTFromLoadIntrData(TLI, DL, Ty, MaxNumLanes);
1341
1342 // TFE intrinsics return an aggregate type.
1343 assert(ST->getNumContainedTypes() == 2 &&
1344 ST->getContainedType(1)->isIntegerTy(32));
1345 return memVTFromLoadIntrData(TLI, DL, ST->getContainedType(0), MaxNumLanes);
1346}
1347
1348/// Map address space 7 to MVT::amdgpuBufferFatPointer because that's its
1349/// in-memory representation. This return value is a custom type because there
1350/// is no MVT::i160 and adding one breaks integer promotion logic. While this
1351/// could cause issues during codegen, these address space 7 pointers will be
1352/// rewritten away by then. Therefore, we can return MVT::amdgpuBufferFatPointer
1353/// in order to allow pre-codegen passes that query TargetTransformInfo, often
1354/// for cost modeling, to work. (This also sets us up decently for doing the
1355/// buffer lowering in GlobalISel if SelectionDAG ever goes away.)
1357 if (AMDGPUAS::BUFFER_FAT_POINTER == AS && DL.getPointerSizeInBits(AS) == 160)
1358 return MVT::amdgpuBufferFatPointer;
1360 DL.getPointerSizeInBits(AS) == 192)
1361 return MVT::amdgpuBufferStridedPointer;
1363}
1364/// Similarly, the in-memory representation of a p7 is {p8, i32}, aka
1365/// v8i32 when padding is added.
1366/// The in-memory representation of a p9 is {p8, i32, i32}, which is
1367/// also v8i32 with padding.
1369 if ((AMDGPUAS::BUFFER_FAT_POINTER == AS &&
1370 DL.getPointerSizeInBits(AS) == 160) ||
1372 DL.getPointerSizeInBits(AS) == 192))
1373 return MVT::v8i32;
1375}
1376
1377static unsigned getIntrMemWidth(unsigned IntrID) {
1378 switch (IntrID) {
1379 case Intrinsic::amdgcn_global_load_async_to_lds_b8:
1380 case Intrinsic::amdgcn_cluster_load_async_to_lds_b8:
1381 case Intrinsic::amdgcn_global_store_async_from_lds_b8:
1382 return 8;
1383 case Intrinsic::amdgcn_global_load_async_to_lds_b32:
1384 case Intrinsic::amdgcn_cluster_load_async_to_lds_b32:
1385 case Intrinsic::amdgcn_global_store_async_from_lds_b32:
1386 case Intrinsic::amdgcn_cooperative_atomic_load_32x4B:
1387 case Intrinsic::amdgcn_cooperative_atomic_store_32x4B:
1388 case Intrinsic::amdgcn_flat_load_monitor_b32:
1389 case Intrinsic::amdgcn_global_load_monitor_b32:
1390 return 32;
1391 case Intrinsic::amdgcn_global_load_async_to_lds_b64:
1392 case Intrinsic::amdgcn_cluster_load_async_to_lds_b64:
1393 case Intrinsic::amdgcn_global_store_async_from_lds_b64:
1394 case Intrinsic::amdgcn_cooperative_atomic_load_16x8B:
1395 case Intrinsic::amdgcn_cooperative_atomic_store_16x8B:
1396 case Intrinsic::amdgcn_flat_load_monitor_b64:
1397 case Intrinsic::amdgcn_global_load_monitor_b64:
1398 return 64;
1399 case Intrinsic::amdgcn_global_load_async_to_lds_b128:
1400 case Intrinsic::amdgcn_cluster_load_async_to_lds_b128:
1401 case Intrinsic::amdgcn_global_store_async_from_lds_b128:
1402 case Intrinsic::amdgcn_cooperative_atomic_load_8x16B:
1403 case Intrinsic::amdgcn_cooperative_atomic_store_8x16B:
1404 case Intrinsic::amdgcn_flat_load_monitor_b128:
1405 case Intrinsic::amdgcn_global_load_monitor_b128:
1406 return 128;
1407 default:
1408 llvm_unreachable("Unknown width");
1409 }
1410}
1411
1413 unsigned ArgIdx) {
1414 Value *OrderingArg = CI.getArgOperand(ArgIdx);
1415 unsigned Ord = cast<ConstantInt>(OrderingArg)->getZExtValue();
1416 switch (AtomicOrderingCABI(Ord)) {
1419 break;
1422 break;
1425 break;
1426 default:
1428 }
1429}
1430
1431static unsigned parseSyncscopeMDArg(const CallBase &CI, unsigned ArgIdx) {
1432 MDNode *ScopeMD = cast<MDNode>(
1433 cast<MetadataAsValue>(CI.getArgOperand(ArgIdx))->getMetadata());
1434 StringRef Scope = cast<MDString>(ScopeMD->getOperand(0))->getString();
1435 return CI.getContext().getOrInsertSyncScopeID(Scope);
1436}
1437
1439 const CallBase &CI,
1440 MachineFunction &MF,
1441 unsigned IntrID) const {
1443 if (CI.hasMetadata(LLVMContext::MD_invariant_load))
1445 if (CI.hasMetadata(LLVMContext::MD_nontemporal))
1447 Flags |= getTargetMMOFlags(CI);
1448
1449 if (const AMDGPU::RsrcIntrinsic *RsrcIntr =
1451 AttributeSet Attr =
1453 MemoryEffects ME = Attr.getMemoryEffects();
1454 if (ME.doesNotAccessMemory())
1455 return;
1456
1457 bool IsSPrefetch = IntrID == Intrinsic::amdgcn_s_buffer_prefetch_data;
1458 if (!IsSPrefetch) {
1459 auto *Aux = cast<ConstantInt>(CI.getArgOperand(CI.arg_size() - 1));
1460 if (Aux->getZExtValue() & AMDGPU::CPol::VOLATILE)
1462 }
1463
1465
1466 IntrinsicInfo Info;
1467 // TODO: Should images get their own address space?
1469
1470 const AMDGPU::MIMGBaseOpcodeInfo *BaseOpcode = nullptr;
1471 if (RsrcIntr->IsImage) {
1472 const AMDGPU::ImageDimIntrinsicInfo *Intr =
1474 BaseOpcode = AMDGPU::getMIMGBaseOpcodeInfo(Intr->BaseOpcode);
1475 Info.align.reset();
1476 }
1477
1478 Value *RsrcArg = CI.getArgOperand(RsrcIntr->RsrcArg);
1479 if (auto *RsrcPtrTy = dyn_cast<PointerType>(RsrcArg->getType())) {
1480 if (RsrcPtrTy->getAddressSpace() == AMDGPUAS::BUFFER_RESOURCE)
1481 // We conservatively set the memory operand of a buffer intrinsic to the
1482 // base resource pointer, so that we can access alias information about
1483 // those pointers. Cases like "this points at the same value
1484 // but with a different offset" are handled in
1485 // areMemAccessesTriviallyDisjoint.
1486 Info.ptrVal = RsrcArg;
1487 }
1488
1489 if (ME.onlyReadsMemory()) {
1490 if (RsrcIntr->IsImage) {
1491 unsigned MaxNumLanes = 4;
1492
1493 if (!BaseOpcode->Gather4) {
1494 // If this isn't a gather, we may have excess loaded elements in the
1495 // IR type. Check the dmask for the real number of elements loaded.
1496 unsigned DMask =
1497 cast<ConstantInt>(CI.getArgOperand(0))->getZExtValue();
1498 MaxNumLanes = DMask == 0 ? 1 : llvm::popcount(DMask);
1499 }
1500
1501 Info.memVT = memVTFromLoadIntrReturn(*this, MF.getDataLayout(),
1502 CI.getType(), MaxNumLanes);
1503 } else {
1504 Info.memVT =
1506 std::numeric_limits<unsigned>::max());
1507 }
1508
1509 // FIXME: What does alignment mean for an image?
1510 Info.opc = ISD::INTRINSIC_W_CHAIN;
1511 Info.flags = Flags | MachineMemOperand::MOLoad;
1512 } else if (ME.onlyWritesMemory()) {
1513 Info.opc = ISD::INTRINSIC_VOID;
1514
1515 Type *DataTy = CI.getArgOperand(0)->getType();
1516 if (RsrcIntr->IsImage) {
1517 unsigned DMask = cast<ConstantInt>(CI.getArgOperand(1))->getZExtValue();
1518 unsigned DMaskLanes = DMask == 0 ? 1 : llvm::popcount(DMask);
1519 Info.memVT = memVTFromLoadIntrData(*this, MF.getDataLayout(), DataTy,
1520 DMaskLanes);
1521 } else
1522 Info.memVT = getValueType(MF.getDataLayout(), DataTy);
1523
1524 Info.flags = Flags | MachineMemOperand::MOStore;
1525 } else {
1526 // Atomic, NoReturn Sampler or prefetch
1527 Info.opc = CI.getType()->isVoidTy() ? ISD::INTRINSIC_VOID
1529
1530 switch (IntrID) {
1531 default:
1532 Info.flags = Flags | MachineMemOperand::MOLoad;
1533 if (!IsSPrefetch)
1534 Info.flags |= MachineMemOperand::MOStore;
1535
1536 if ((RsrcIntr->IsImage && BaseOpcode->NoReturn) || IsSPrefetch) {
1537 // Fake memory access type for no return sampler intrinsics
1538 Info.memVT = MVT::i32;
1539 } else {
1540 // XXX - Should this be volatile without known ordering?
1541 Info.flags |= MachineMemOperand::MOVolatile;
1542 Info.memVT = MVT::getVT(CI.getArgOperand(0)->getType());
1543 }
1544 break;
1545 case Intrinsic::amdgcn_raw_buffer_load_lds:
1546 case Intrinsic::amdgcn_raw_buffer_load_async_lds:
1547 case Intrinsic::amdgcn_raw_ptr_buffer_load_lds:
1548 case Intrinsic::amdgcn_raw_ptr_buffer_load_async_lds:
1549 case Intrinsic::amdgcn_struct_buffer_load_lds:
1550 case Intrinsic::amdgcn_struct_buffer_load_async_lds:
1551 case Intrinsic::amdgcn_struct_ptr_buffer_load_lds:
1552 case Intrinsic::amdgcn_struct_ptr_buffer_load_async_lds: {
1553 unsigned Width = cast<ConstantInt>(CI.getArgOperand(2))->getZExtValue();
1554
1555 // Entry 0: Load from buffer.
1556 // Don't set an offset, since the pointer value always represents the
1557 // base of the buffer.
1558 Info.memVT = EVT::getIntegerVT(CI.getContext(), Width * 8);
1559 Info.flags = Flags | MachineMemOperand::MOLoad;
1560 Infos.push_back(Info);
1561
1562 // Entry 1: Store to LDS.
1563 // Instruction offset is applied, and an additional per-lane offset
1564 // which we simulate using a larger memory type.
1565 Info.memVT = EVT::getIntegerVT(
1566 CI.getContext(), Width * 8 * Subtarget->getWavefrontSize());
1567 Info.ptrVal = CI.getArgOperand(1); // LDS destination pointer
1568 Info.offset = cast<ConstantInt>(CI.getArgOperand(CI.arg_size() - 2))
1569 ->getZExtValue();
1570 Info.fallbackAddressSpace = AMDGPUAS::LOCAL_ADDRESS;
1571 Info.flags = Flags | MachineMemOperand::MOStore;
1572 Infos.push_back(Info);
1573 return;
1574 }
1575 case Intrinsic::amdgcn_raw_atomic_buffer_load:
1576 case Intrinsic::amdgcn_raw_ptr_atomic_buffer_load:
1577 case Intrinsic::amdgcn_struct_atomic_buffer_load:
1578 case Intrinsic::amdgcn_struct_ptr_atomic_buffer_load: {
1579 Info.memVT =
1581 std::numeric_limits<unsigned>::max());
1582 Info.flags = Flags | MachineMemOperand::MOLoad;
1583 Infos.push_back(Info);
1584 return;
1585 }
1586 }
1587 }
1588 Infos.push_back(Info);
1589 return;
1590 }
1591
1592 IntrinsicInfo Info;
1593 switch (IntrID) {
1594 case Intrinsic::amdgcn_ds_ordered_add:
1595 case Intrinsic::amdgcn_ds_ordered_swap: {
1596 Info.opc = ISD::INTRINSIC_W_CHAIN;
1597 Info.memVT = MVT::getVT(CI.getType());
1598 Info.ptrVal = CI.getOperand(0);
1599 Info.align.reset();
1601
1602 const ConstantInt *Vol = cast<ConstantInt>(CI.getOperand(4));
1603 if (!Vol->isZero())
1604 Info.flags |= MachineMemOperand::MOVolatile;
1605
1606 Infos.push_back(Info);
1607 return;
1608 }
1609 case Intrinsic::amdgcn_ds_add_gs_reg_rtn:
1610 case Intrinsic::amdgcn_ds_sub_gs_reg_rtn: {
1611 Info.opc = ISD::INTRINSIC_W_CHAIN;
1612 Info.memVT = MVT::getVT(CI.getOperand(0)->getType());
1613 Info.ptrVal = nullptr;
1614 Info.fallbackAddressSpace = AMDGPUAS::STREAMOUT_REGISTER;
1616 Infos.push_back(Info);
1617 return;
1618 }
1619 case Intrinsic::amdgcn_ds_append:
1620 case Intrinsic::amdgcn_ds_consume: {
1621 Info.opc = ISD::INTRINSIC_W_CHAIN;
1622 Info.memVT = MVT::getVT(CI.getType());
1623 Info.ptrVal = CI.getOperand(0);
1624 Info.align.reset();
1626
1627 const ConstantInt *Vol = cast<ConstantInt>(CI.getOperand(1));
1628 if (!Vol->isZero())
1629 Info.flags |= MachineMemOperand::MOVolatile;
1630
1631 Infos.push_back(Info);
1632 return;
1633 }
1634 case Intrinsic::amdgcn_ds_atomic_async_barrier_arrive_b64:
1635 case Intrinsic::amdgcn_ds_atomic_barrier_arrive_rtn_b64: {
1636 Info.opc = (IntrID == Intrinsic::amdgcn_ds_atomic_barrier_arrive_rtn_b64)
1639 Info.memVT = MVT::getVT(CI.getType());
1640 Info.ptrVal = CI.getOperand(0);
1641 Info.memVT = MVT::i64;
1642 Info.size = 8;
1643 Info.align.reset();
1645 Info.order = AtomicOrdering::Monotonic;
1646 Infos.push_back(Info);
1647 return;
1648 }
1649 case Intrinsic::amdgcn_image_bvh_dual_intersect_ray:
1650 case Intrinsic::amdgcn_image_bvh_intersect_ray:
1651 case Intrinsic::amdgcn_image_bvh8_intersect_ray: {
1652 Info.opc = ISD::INTRINSIC_W_CHAIN;
1653 Info.memVT =
1654 MVT::getVT(IntrID == Intrinsic::amdgcn_image_bvh_intersect_ray
1655 ? CI.getType()
1657 ->getElementType(0)); // XXX: what is correct VT?
1658
1659 Info.fallbackAddressSpace = AMDGPUAS::BUFFER_RESOURCE;
1660 Info.align.reset();
1661 Info.flags = Flags | MachineMemOperand::MOLoad |
1663 Infos.push_back(Info);
1664 return;
1665 }
1666 case Intrinsic::amdgcn_global_atomic_fmin_num:
1667 case Intrinsic::amdgcn_global_atomic_fmax_num:
1668 case Intrinsic::amdgcn_global_atomic_ordered_add_b64:
1669 case Intrinsic::amdgcn_flat_atomic_fmin_num:
1670 case Intrinsic::amdgcn_flat_atomic_fmax_num: {
1671 Info.opc = ISD::INTRINSIC_W_CHAIN;
1672 Info.memVT = MVT::getVT(CI.getType());
1673 Info.ptrVal = CI.getOperand(0);
1674 Info.align.reset();
1675 Info.flags =
1678 Infos.push_back(Info);
1679 return;
1680 }
1681 case Intrinsic::amdgcn_cluster_load_b32:
1682 case Intrinsic::amdgcn_cluster_load_b64:
1683 case Intrinsic::amdgcn_cluster_load_b128:
1684 case Intrinsic::amdgcn_ds_load_tr6_b96:
1685 case Intrinsic::amdgcn_ds_load_tr4_b64:
1686 case Intrinsic::amdgcn_ds_load_tr8_b64:
1687 case Intrinsic::amdgcn_ds_load_tr16_b128:
1688 case Intrinsic::amdgcn_global_load_tr6_b96:
1689 case Intrinsic::amdgcn_global_load_tr4_b64:
1690 case Intrinsic::amdgcn_global_load_tr_b64:
1691 case Intrinsic::amdgcn_global_load_tr_b128:
1692 case Intrinsic::amdgcn_ds_read_tr4_b64:
1693 case Intrinsic::amdgcn_ds_read_tr6_b96:
1694 case Intrinsic::amdgcn_ds_read_tr8_b64:
1695 case Intrinsic::amdgcn_ds_read_tr16_b64: {
1696 Info.opc = ISD::INTRINSIC_W_CHAIN;
1697 Info.memVT = MVT::getVT(CI.getType());
1698 Info.ptrVal = CI.getOperand(0);
1699 Info.align.reset();
1700 Info.flags = Flags | MachineMemOperand::MOLoad;
1701 Infos.push_back(Info);
1702 return;
1703 }
1704 case Intrinsic::amdgcn_flat_load_monitor_b32:
1705 case Intrinsic::amdgcn_flat_load_monitor_b64:
1706 case Intrinsic::amdgcn_flat_load_monitor_b128:
1707 case Intrinsic::amdgcn_global_load_monitor_b32:
1708 case Intrinsic::amdgcn_global_load_monitor_b64:
1709 case Intrinsic::amdgcn_global_load_monitor_b128: {
1710 Info.opc = ISD::INTRINSIC_W_CHAIN;
1711 Info.memVT = EVT::getIntegerVT(CI.getContext(), getIntrMemWidth(IntrID));
1712 Info.ptrVal = CI.getOperand(0);
1713 Info.align.reset();
1714 Info.flags = MachineMemOperand::MOLoad;
1715 Info.order = parseAtomicOrderingCABIArg(CI, 1);
1716 Info.ssid = parseSyncscopeMDArg(CI, 2);
1717 Infos.push_back(Info);
1718 return;
1719 }
1720 case Intrinsic::amdgcn_cooperative_atomic_load_32x4B:
1721 case Intrinsic::amdgcn_cooperative_atomic_load_16x8B:
1722 case Intrinsic::amdgcn_cooperative_atomic_load_8x16B: {
1723 Info.opc = ISD::INTRINSIC_W_CHAIN;
1724 Info.memVT = EVT::getIntegerVT(CI.getContext(), getIntrMemWidth(IntrID));
1725 Info.ptrVal = CI.getOperand(0);
1726 Info.align.reset();
1728 Info.order = parseAtomicOrderingCABIArg(CI, 1);
1729 Info.ssid = parseSyncscopeMDArg(CI, 2);
1730 Infos.push_back(Info);
1731 return;
1732 }
1733 case Intrinsic::amdgcn_cooperative_atomic_store_32x4B:
1734 case Intrinsic::amdgcn_cooperative_atomic_store_16x8B:
1735 case Intrinsic::amdgcn_cooperative_atomic_store_8x16B: {
1736 Info.opc = ISD::INTRINSIC_VOID;
1737 Info.memVT = EVT::getIntegerVT(CI.getContext(), getIntrMemWidth(IntrID));
1738 Info.ptrVal = CI.getArgOperand(0);
1739 Info.align.reset();
1741 Info.order = parseAtomicOrderingCABIArg(CI, 2);
1742 Info.ssid = parseSyncscopeMDArg(CI, 3);
1743 Infos.push_back(Info);
1744 return;
1745 }
1746 case Intrinsic::amdgcn_ds_gws_init:
1747 case Intrinsic::amdgcn_ds_gws_barrier:
1748 case Intrinsic::amdgcn_ds_gws_sema_v:
1749 case Intrinsic::amdgcn_ds_gws_sema_br:
1750 case Intrinsic::amdgcn_ds_gws_sema_p:
1751 case Intrinsic::amdgcn_ds_gws_sema_release_all: {
1752 Info.opc = ISD::INTRINSIC_VOID;
1753
1754 const GCNTargetMachine &TM =
1755 static_cast<const GCNTargetMachine &>(getTargetMachine());
1756
1758 Info.ptrVal = MFI->getGWSPSV(TM);
1759
1760 // This is an abstract access, but we need to specify a type and size.
1761 Info.memVT = MVT::i32;
1762 Info.size = 4;
1763 Info.align = Align(4);
1764
1765 if (IntrID == Intrinsic::amdgcn_ds_gws_barrier)
1766 Info.flags = Flags | MachineMemOperand::MOLoad;
1767 else
1768 Info.flags = Flags | MachineMemOperand::MOStore;
1769 Infos.push_back(Info);
1770 return;
1771 }
1772 case Intrinsic::amdgcn_global_load_async_to_lds_b8:
1773 case Intrinsic::amdgcn_global_load_async_to_lds_b32:
1774 case Intrinsic::amdgcn_global_load_async_to_lds_b64:
1775 case Intrinsic::amdgcn_global_load_async_to_lds_b128:
1776 case Intrinsic::amdgcn_cluster_load_async_to_lds_b8:
1777 case Intrinsic::amdgcn_cluster_load_async_to_lds_b32:
1778 case Intrinsic::amdgcn_cluster_load_async_to_lds_b64:
1779 case Intrinsic::amdgcn_cluster_load_async_to_lds_b128: {
1780 // Entry 0: Load from source (global/flat).
1781 Info.opc = ISD::INTRINSIC_VOID;
1782 Info.memVT = EVT::getIntegerVT(CI.getContext(), getIntrMemWidth(IntrID));
1783 Info.ptrVal = CI.getArgOperand(0); // Global pointer
1784 Info.offset = cast<ConstantInt>(CI.getArgOperand(2))->getSExtValue();
1785 Info.flags = Flags | MachineMemOperand::MOLoad;
1786 Infos.push_back(Info);
1787
1788 // Entry 1: Store to LDS (same offset).
1789 Info.flags = Flags | MachineMemOperand::MOStore;
1790 Info.ptrVal = CI.getArgOperand(1); // LDS pointer
1791 Infos.push_back(Info);
1792 return;
1793 }
1794 case Intrinsic::amdgcn_global_store_async_from_lds_b8:
1795 case Intrinsic::amdgcn_global_store_async_from_lds_b32:
1796 case Intrinsic::amdgcn_global_store_async_from_lds_b64:
1797 case Intrinsic::amdgcn_global_store_async_from_lds_b128: {
1798 // Entry 0: Load from LDS.
1799 Info.opc = ISD::INTRINSIC_VOID;
1800 Info.memVT = EVT::getIntegerVT(CI.getContext(), getIntrMemWidth(IntrID));
1801 Info.ptrVal = CI.getArgOperand(1); // LDS pointer
1802 Info.offset = cast<ConstantInt>(CI.getArgOperand(2))->getSExtValue();
1803 Info.flags = Flags | MachineMemOperand::MOLoad;
1804 Infos.push_back(Info);
1805
1806 // Entry 1: Store to global (same offset).
1807 Info.flags = Flags | MachineMemOperand::MOStore;
1808 Info.ptrVal = CI.getArgOperand(0); // Global pointer
1809 Infos.push_back(Info);
1810 return;
1811 }
1812 case Intrinsic::amdgcn_av_load_b128:
1813 case Intrinsic::amdgcn_av_store_b128: {
1814 bool IsStore = IntrID == Intrinsic::amdgcn_av_store_b128;
1815 Info.opc = IsStore ? ISD::INTRINSIC_VOID : ISD::INTRINSIC_W_CHAIN;
1816 Info.memVT = MVT::v4i32;
1817 Info.ptrVal = CI.getArgOperand(0);
1818 Info.align = Align(16);
1819 Info.flags |=
1821 // Pretend to be atomic so that SIMemoryLegalizer::expandStore sets cache
1822 // flags appropriately.
1823 Info.order = AtomicOrdering::Monotonic;
1824
1825 LLVMContext &Ctx = CI.getContext();
1826 unsigned ScopeIdx = CI.arg_size() - 1;
1827 MDNode *ScopeMD = cast<MDNode>(
1828 cast<MetadataAsValue>(CI.getArgOperand(ScopeIdx))->getMetadata());
1829 StringRef Scope = cast<MDString>(ScopeMD->getOperand(0))->getString();
1830 Info.ssid = Ctx.getOrInsertSyncScopeID(Scope);
1831 Infos.push_back(Info);
1832 return;
1833 }
1834 case Intrinsic::amdgcn_load_to_lds:
1835 case Intrinsic::amdgcn_load_async_to_lds:
1836 case Intrinsic::amdgcn_global_load_lds:
1837 case Intrinsic::amdgcn_global_load_async_lds: {
1838 unsigned Width = cast<ConstantInt>(CI.getArgOperand(2))->getZExtValue();
1839 auto *Aux = cast<ConstantInt>(CI.getArgOperand(CI.arg_size() - 1));
1840 bool IsVolatile = Aux->getZExtValue() & AMDGPU::CPol::VOLATILE;
1841 if (IsVolatile)
1843
1844 // Entry 0: Load from source (global/flat).
1845 Info.opc = ISD::INTRINSIC_VOID;
1846 Info.memVT = EVT::getIntegerVT(CI.getContext(), Width * 8);
1847 Info.ptrVal = CI.getArgOperand(0); // Source pointer
1848 Info.offset = cast<ConstantInt>(CI.getArgOperand(3))->getSExtValue();
1849 Info.flags = Flags | MachineMemOperand::MOLoad;
1850 Infos.push_back(Info);
1851
1852 // Entry 1: Store to LDS.
1853 // Same offset from the instruction, but an additional per-lane offset is
1854 // added. Represent that using a wider memory type.
1855 Info.memVT = EVT::getIntegerVT(CI.getContext(),
1856 Width * 8 * Subtarget->getWavefrontSize());
1857 Info.ptrVal = CI.getArgOperand(1); // LDS destination pointer
1858 Info.flags = Flags | MachineMemOperand::MOStore;
1859 Infos.push_back(Info);
1860 return;
1861 }
1862 case Intrinsic::amdgcn_ds_bvh_stack_rtn:
1863 case Intrinsic::amdgcn_ds_bvh_stack_push4_pop1_rtn:
1864 case Intrinsic::amdgcn_ds_bvh_stack_push8_pop1_rtn:
1865 case Intrinsic::amdgcn_ds_bvh_stack_push8_pop2_rtn: {
1866 Info.opc = ISD::INTRINSIC_W_CHAIN;
1867
1868 const GCNTargetMachine &TM =
1869 static_cast<const GCNTargetMachine &>(getTargetMachine());
1870
1872 Info.ptrVal = MFI->getGWSPSV(TM);
1873
1874 // This is an abstract access, but we need to specify a type and size.
1875 Info.memVT = MVT::i32;
1876 Info.size = 4;
1877 Info.align = Align(4);
1878
1880 Infos.push_back(Info);
1881 return;
1882 }
1883 case Intrinsic::amdgcn_s_prefetch_data:
1884 case Intrinsic::amdgcn_s_prefetch_inst:
1885 case Intrinsic::amdgcn_flat_prefetch:
1886 case Intrinsic::amdgcn_global_prefetch: {
1887 Info.opc = ISD::INTRINSIC_VOID;
1888 Info.memVT = EVT::getIntegerVT(CI.getContext(), 8);
1889 Info.ptrVal = CI.getArgOperand(0);
1890 Info.flags = Flags | MachineMemOperand::MOLoad;
1891 Infos.push_back(Info);
1892 return;
1893 }
1894 default:
1895 return;
1896 }
1897}
1898
1900 const CallInst &I, SmallVectorImpl<SDValue> &Ops, SelectionDAG &DAG) const {
1902 case Intrinsic::amdgcn_addrspacecast_nonnull: {
1903 // The DAG's ValueType loses the addrspaces.
1904 // Add them as 2 extra Constant operands "from" and "to".
1905 unsigned SrcAS = I.getOperand(0)->getType()->getPointerAddressSpace();
1906 unsigned DstAS = I.getType()->getPointerAddressSpace();
1907 Ops.push_back(DAG.getTargetConstant(SrcAS, SDLoc(), MVT::i32));
1908 Ops.push_back(DAG.getTargetConstant(DstAS, SDLoc(), MVT::i32));
1909 break;
1910 }
1911 default:
1912 break;
1913 }
1914}
1915
1918 Type *&AccessTy) const {
1919 Value *Ptr = nullptr;
1920 switch (II->getIntrinsicID()) {
1921 case Intrinsic::amdgcn_cluster_load_b128:
1922 case Intrinsic::amdgcn_cluster_load_b64:
1923 case Intrinsic::amdgcn_cluster_load_b32:
1924 case Intrinsic::amdgcn_ds_append:
1925 case Intrinsic::amdgcn_ds_consume:
1926 case Intrinsic::amdgcn_ds_load_tr8_b64:
1927 case Intrinsic::amdgcn_ds_load_tr16_b128:
1928 case Intrinsic::amdgcn_ds_load_tr4_b64:
1929 case Intrinsic::amdgcn_ds_load_tr6_b96:
1930 case Intrinsic::amdgcn_ds_read_tr4_b64:
1931 case Intrinsic::amdgcn_ds_read_tr6_b96:
1932 case Intrinsic::amdgcn_ds_read_tr8_b64:
1933 case Intrinsic::amdgcn_ds_read_tr16_b64:
1934 case Intrinsic::amdgcn_ds_ordered_add:
1935 case Intrinsic::amdgcn_ds_ordered_swap:
1936 case Intrinsic::amdgcn_ds_atomic_async_barrier_arrive_b64:
1937 case Intrinsic::amdgcn_ds_atomic_barrier_arrive_rtn_b64:
1938 case Intrinsic::amdgcn_flat_atomic_fmax_num:
1939 case Intrinsic::amdgcn_flat_atomic_fmin_num:
1940 case Intrinsic::amdgcn_global_atomic_fmax_num:
1941 case Intrinsic::amdgcn_global_atomic_fmin_num:
1942 case Intrinsic::amdgcn_global_atomic_ordered_add_b64:
1943 case Intrinsic::amdgcn_global_load_tr_b64:
1944 case Intrinsic::amdgcn_global_load_tr_b128:
1945 case Intrinsic::amdgcn_global_load_tr4_b64:
1946 case Intrinsic::amdgcn_global_load_tr6_b96:
1947 case Intrinsic::amdgcn_global_store_async_from_lds_b8:
1948 case Intrinsic::amdgcn_global_store_async_from_lds_b32:
1949 case Intrinsic::amdgcn_global_store_async_from_lds_b64:
1950 case Intrinsic::amdgcn_global_store_async_from_lds_b128:
1951 case Intrinsic::amdgcn_av_load_b128:
1952 case Intrinsic::amdgcn_av_store_b128:
1953 Ptr = II->getArgOperand(0);
1954 break;
1955 case Intrinsic::amdgcn_load_to_lds:
1956 case Intrinsic::amdgcn_load_async_to_lds:
1957 case Intrinsic::amdgcn_global_load_lds:
1958 case Intrinsic::amdgcn_global_load_async_lds:
1959 case Intrinsic::amdgcn_global_load_async_to_lds_b8:
1960 case Intrinsic::amdgcn_global_load_async_to_lds_b32:
1961 case Intrinsic::amdgcn_global_load_async_to_lds_b64:
1962 case Intrinsic::amdgcn_global_load_async_to_lds_b128:
1963 case Intrinsic::amdgcn_cluster_load_async_to_lds_b8:
1964 case Intrinsic::amdgcn_cluster_load_async_to_lds_b32:
1965 case Intrinsic::amdgcn_cluster_load_async_to_lds_b64:
1966 case Intrinsic::amdgcn_cluster_load_async_to_lds_b128:
1967 Ptr = II->getArgOperand(1);
1968 break;
1969 default:
1970 return false;
1971 }
1972 AccessTy = II->getType();
1973 Ops.push_back(Ptr);
1974 return true;
1975}
1976
1978 unsigned AddrSpace) const {
1979 if (!Subtarget->hasFlatInstOffsets()) {
1980 // Flat instructions do not have offsets, and only have the register
1981 // address.
1982 return AM.BaseOffs == 0 && AM.Scale == 0;
1983 }
1984
1986 FlatAddrSpace FlatVariant =
1987 AddrSpace == AMDGPUAS::GLOBAL_ADDRESS ? FlatAddrSpace::FlatGlobal
1988 : AddrSpace == AMDGPUAS::PRIVATE_ADDRESS ? FlatAddrSpace::FlatScratch
1989 : FlatAddrSpace::FLAT;
1990
1991 return AM.Scale == 0 &&
1992 (AM.BaseOffs == 0 || Subtarget->getInstrInfo()->isLegalFLATOffset(
1993 AM.BaseOffs, AddrSpace, FlatVariant));
1994}
1995
1997 if (Subtarget->hasFlatGlobalInsts())
1999
2000 if (!Subtarget->hasAddr64() || Subtarget->useFlatForGlobal()) {
2001 // Assume the we will use FLAT for all global memory accesses
2002 // on VI.
2003 // FIXME: This assumption is currently wrong. On VI we still use
2004 // MUBUF instructions for the r + i addressing mode. As currently
2005 // implemented, the MUBUF instructions only work on buffer < 4GB.
2006 // It may be possible to support > 4GB buffers with MUBUF instructions,
2007 // by setting the stride value in the resource descriptor which would
2008 // increase the size limit to (stride * 4GB). However, this is risky,
2009 // because it has never been validated.
2011 }
2012
2013 return isLegalMUBUFAddressingMode(AM);
2014}
2015
2016bool SITargetLowering::isLegalMUBUFAddressingMode(const AddrMode &AM) const {
2017 // MUBUF / MTBUF instructions have a 12-bit unsigned byte offset, and
2018 // additionally can do r + r + i with addr64. 32-bit has more addressing
2019 // mode options. Depending on the resource constant, it can also do
2020 // (i64 r0) + (i32 r1) * (i14 i).
2021 //
2022 // Private arrays end up using a scratch buffer most of the time, so also
2023 // assume those use MUBUF instructions. Scratch loads / stores are currently
2024 // implemented as mubuf instructions with offen bit set, so slightly
2025 // different than the normal addr64.
2026 const SIInstrInfo *TII = Subtarget->getInstrInfo();
2027 if (!TII->isLegalMUBUFImmOffset(AM.BaseOffs))
2028 return false;
2029
2030 // FIXME: Since we can split immediate into soffset and immediate offset,
2031 // would it make sense to allow any immediate?
2032
2033 switch (AM.Scale) {
2034 case 0: // r + i or just i, depending on HasBaseReg.
2035 return true;
2036 case 1:
2037 return true; // We have r + r or r + i.
2038 case 2:
2039 if (AM.HasBaseReg) {
2040 // Reject 2 * r + r.
2041 return false;
2042 }
2043
2044 // Allow 2 * r as r + r
2045 // Or 2 * r + i is allowed as r + r + i.
2046 return true;
2047 default: // Don't allow n * r
2048 return false;
2049 }
2050}
2051
2053 const AddrMode &AM, Type *Ty,
2054 unsigned AS,
2055 Instruction *I) const {
2056 // No global is ever allowed as a base.
2057 if (AM.BaseGV)
2058 return false;
2059
2060 if (AS == AMDGPUAS::GLOBAL_ADDRESS)
2061 return isLegalGlobalAddressingMode(AM);
2062
2063 if (AS == AMDGPUAS::CONSTANT_ADDRESS ||
2067 // If the offset isn't a multiple of 4, it probably isn't going to be
2068 // correctly aligned.
2069 // FIXME: Can we get the real alignment here?
2070 if (AM.BaseOffs % 4 != 0)
2071 return isLegalMUBUFAddressingMode(AM);
2072
2073 if (!Subtarget->hasScalarSubwordLoads()) {
2074 // There are no SMRD extloads, so if we have to do a small type access we
2075 // will use a MUBUF load.
2076 // FIXME?: We also need to do this if unaligned, but we don't know the
2077 // alignment here.
2078 if (Ty->isSized() && DL.getTypeStoreSize(Ty) < 4)
2079 return isLegalGlobalAddressingMode(AM);
2080 }
2081
2082 if (Subtarget->getGeneration() == AMDGPUSubtarget::SOUTHERN_ISLANDS) {
2083 // SMRD instructions have an 8-bit, dword offset on SI.
2084 if (!isUInt<8>(AM.BaseOffs / 4))
2085 return false;
2086 } else if (Subtarget->getGeneration() == AMDGPUSubtarget::SEA_ISLANDS) {
2087 // On CI+, this can also be a 32-bit literal constant offset. If it fits
2088 // in 8-bits, it can use a smaller encoding.
2089 if (!isUInt<32>(AM.BaseOffs / 4))
2090 return false;
2091 } else if (Subtarget->getGeneration() < AMDGPUSubtarget::GFX9) {
2092 // On VI, these use the SMEM format and the offset is 20-bit in bytes.
2093 if (!isUInt<20>(AM.BaseOffs))
2094 return false;
2095 } else if (Subtarget->getGeneration() < AMDGPUSubtarget::GFX12) {
2096 // On GFX9 the offset is signed 21-bit in bytes (but must not be negative
2097 // for S_BUFFER_* instructions).
2098 if (!isInt<21>(AM.BaseOffs))
2099 return false;
2100 } else {
2101 // On GFX12, all offsets are signed 24-bit in bytes.
2102 if (!isInt<24>(AM.BaseOffs))
2103 return false;
2104 }
2105
2106 if ((AS == AMDGPUAS::CONSTANT_ADDRESS ||
2108 AM.BaseOffs < 0) {
2109 // Scalar (non-buffer) loads can only use a negative offset if
2110 // soffset+offset is non-negative. Since the compiler can only prove that
2111 // in a few special cases, it is safer to claim that negative offsets are
2112 // not supported.
2113 return false;
2114 }
2115
2116 if (AM.Scale == 0) // r + i or just i, depending on HasBaseReg.
2117 return true;
2118
2119 if (AM.Scale == 1 && AM.HasBaseReg)
2120 return true;
2121
2122 return false;
2123 }
2124
2125 if (AS == AMDGPUAS::PRIVATE_ADDRESS)
2126 return Subtarget->hasFlatScratchEnabled()
2128 : isLegalMUBUFAddressingMode(AM);
2129
2130 if (AS == AMDGPUAS::LOCAL_ADDRESS ||
2131 (AS == AMDGPUAS::REGION_ADDRESS && Subtarget->hasGDS())) {
2132 // Basic, single offset DS instructions allow a 16-bit unsigned immediate
2133 // field.
2134 // XXX - If doing a 4-byte aligned 8-byte type access, we effectively have
2135 // an 8-bit dword offset but we don't know the alignment here.
2136 if (!isUInt<16>(AM.BaseOffs))
2137 return false;
2138
2139 if (AM.Scale == 0) // r + i or just i, depending on HasBaseReg.
2140 return true;
2141
2142 if (AM.Scale == 1 && AM.HasBaseReg)
2143 return true;
2144
2145 return false;
2146 }
2147
2149 // For an unknown address space, this usually means that this is for some
2150 // reason being used for pure arithmetic, and not based on some addressing
2151 // computation. We don't have instructions that compute pointers with any
2152 // addressing modes, so treat them as having no offset like flat
2153 // instructions.
2155 }
2156
2157 // Assume a user alias of global for unknown address spaces.
2158 return isLegalGlobalAddressingMode(AM);
2159}
2160
2162 const MachineFunction &MF) const {
2164 return (MemVT.getSizeInBits() <= 4 * 32);
2165 if (AS == AMDGPUAS::PRIVATE_ADDRESS) {
2166 unsigned MaxPrivateBits = 8 * getSubtarget()->getMaxPrivateElementSize();
2167 return (MemVT.getSizeInBits() <= MaxPrivateBits);
2168 }
2170 return (MemVT.getSizeInBits() <= 2 * 32);
2171 return true;
2172}
2173
2175 unsigned Size, unsigned AddrSpace, Align Alignment,
2176 MachineMemOperand::Flags Flags, unsigned *IsFast) const {
2177 if (IsFast)
2178 *IsFast = 0;
2179
2180 if (AddrSpace == AMDGPUAS::LOCAL_ADDRESS ||
2181 AddrSpace == AMDGPUAS::REGION_ADDRESS) {
2182 // Check if alignment requirements for ds_read/write instructions are
2183 // disabled.
2184 if (!Subtarget->hasUnalignedDSAccessEnabled() && Alignment < Align(4))
2185 return false;
2186
2187 Align RequiredAlignment(
2188 PowerOf2Ceil(divideCeil(Size, 8))); // Natural alignment.
2189 if (Subtarget->hasLDSMisalignedBugInWGPMode() && Size > 32 &&
2190 Alignment < RequiredAlignment)
2191 return false;
2192
2193 // Either, the alignment requirements are "enabled", or there is an
2194 // unaligned LDS access related hardware bug though alignment requirements
2195 // are "disabled". In either case, we need to check for proper alignment
2196 // requirements.
2197 //
2198 switch (Size) {
2199 case 64:
2200 // SI has a hardware bug in the LDS / GDS bounds checking: if the base
2201 // address is negative, then the instruction is incorrectly treated as
2202 // out-of-bounds even if base + offsets is in bounds. Split vectorized
2203 // loads here to avoid emitting ds_read2_b32. We may re-combine the
2204 // load later in the SILoadStoreOptimizer.
2205 if (!Subtarget->hasUsableDSOffset() && Alignment < Align(8))
2206 return false;
2207
2208 // 8 byte accessing via ds_read/write_b64 require 8-byte alignment, but we
2209 // can do a 4 byte aligned, 8 byte access in a single operation using
2210 // ds_read2/write2_b32 with adjacent offsets.
2211 RequiredAlignment = Align(4);
2212
2213 if (Subtarget->hasUnalignedDSAccessEnabled()) {
2214 // We will either select ds_read_b64/ds_write_b64 or ds_read2_b32/
2215 // ds_write2_b32 depending on the alignment. In either case with either
2216 // alignment there is no faster way of doing this.
2217
2218 // The numbers returned here and below are not additive, it is a 'speed
2219 // rank'. They are just meant to be compared to decide if a certain way
2220 // of lowering an operation is faster than another. For that purpose
2221 // naturally aligned operation gets it bitsize to indicate that "it
2222 // operates with a speed comparable to N-bit wide load". With the full
2223 // alignment ds128 is slower than ds96 for example. If underaligned it
2224 // is comparable to a speed of a single dword access, which would then
2225 // mean 32 < 128 and it is faster to issue a wide load regardless.
2226 // 1 is simply "slow, don't do it". I.e. comparing an aligned load to a
2227 // wider load which will not be aligned anymore the latter is slower.
2228 if (IsFast)
2229 *IsFast = (Alignment >= RequiredAlignment) ? 64
2230 : (Alignment < Align(4)) ? 32
2231 : 1;
2232 return true;
2233 }
2234
2235 break;
2236 case 96:
2237 if (!Subtarget->hasDS96AndDS128())
2238 return false;
2239
2240 // 12 byte accessing via ds_read/write_b96 require 16-byte alignment on
2241 // gfx8 and older.
2242
2243 if (Subtarget->hasUnalignedDSAccessEnabled()) {
2244 // Naturally aligned access is fastest. However, also report it is Fast
2245 // if memory is aligned less than DWORD. A narrow load or store will be
2246 // be equally slow as a single ds_read_b96/ds_write_b96, but there will
2247 // be more of them, so overall we will pay less penalty issuing a single
2248 // instruction.
2249
2250 // See comment on the values above.
2251 if (IsFast)
2252 *IsFast = (Alignment >= RequiredAlignment) ? 96
2253 : (Alignment < Align(4)) ? 32
2254 : 1;
2255 return true;
2256 }
2257
2258 break;
2259 case 128:
2260 if (!Subtarget->hasDS96AndDS128() || !Subtarget->useDS128())
2261 return false;
2262
2263 // 16 byte accessing via ds_read/write_b128 require 16-byte alignment on
2264 // gfx8 and older, but we can do a 8 byte aligned, 16 byte access in a
2265 // single operation using ds_read2/write2_b64.
2266 RequiredAlignment = Align(8);
2267
2268 if (Subtarget->hasUnalignedDSAccessEnabled()) {
2269 // Naturally aligned access is fastest. However, also report it is Fast
2270 // if memory is aligned less than DWORD. A narrow load or store will be
2271 // be equally slow as a single ds_read_b128/ds_write_b128, but there
2272 // will be more of them, so overall we will pay less penalty issuing a
2273 // single instruction.
2274
2275 // See comment on the values above.
2276 if (IsFast)
2277 *IsFast = (Alignment >= RequiredAlignment) ? 128
2278 : (Alignment < Align(4)) ? 32
2279 : 1;
2280 return true;
2281 }
2282
2283 break;
2284 default:
2285 if (Size > 32)
2286 return false;
2287
2288 break;
2289 }
2290
2291 // See comment on the values above.
2292 // Note that we have a single-dword or sub-dword here, so if underaligned
2293 // it is a slowest possible access, hence returned value is 0.
2294 if (IsFast)
2295 *IsFast = (Alignment >= RequiredAlignment) ? Size : 0;
2296
2297 return Alignment >= RequiredAlignment ||
2298 Subtarget->hasUnalignedDSAccessEnabled();
2299 }
2300
2301 // FIXME: We have to be conservative here and assume that flat operations
2302 // will access scratch. If we had access to the IR function, then we
2303 // could determine if any private memory was used in the function.
2304 if (AddrSpace == AMDGPUAS::PRIVATE_ADDRESS ||
2305 AddrSpace == AMDGPUAS::FLAT_ADDRESS) {
2306 bool AlignedBy4 = Alignment >= Align(4);
2307 if (Subtarget->hasUnalignedScratchAccessEnabled()) {
2308 if (IsFast)
2309 *IsFast = AlignedBy4 ? Size : 1;
2310 return true;
2311 }
2312
2313 if (IsFast)
2314 *IsFast = AlignedBy4;
2315
2316 return AlignedBy4;
2317 }
2318
2319 // So long as they are correct, wide global memory operations perform better
2320 // than multiple smaller memory ops -- even when misaligned
2321 if (AMDGPU::isExtendedGlobalAddrSpace(AddrSpace)) {
2322 if (IsFast)
2323 *IsFast = Size;
2324
2325 return Alignment >= Align(4) ||
2326 Subtarget->hasUnalignedBufferAccessEnabled();
2327 }
2328
2329 // Ensure robust out-of-bounds guarantees for buffer accesses are met when the
2330 // "amdgpu.buffer.oob.mode" module flag has not enabled relaxed untyped-buffer
2331 // OOB semantics. Normally hardware will ensure proper
2332 // out-of-bounds behavior, but in the edge case where an access starts
2333 // out-of-bounds and then enters in-bounds, the entire access would be treated
2334 // as out-of-bounds. Prevent misaligned memory accesses by requiring the
2335 // natural alignment of buffer accesses.
2336 if (AddrSpace == AMDGPUAS::BUFFER_FAT_POINTER ||
2337 AddrSpace == AMDGPUAS::BUFFER_RESOURCE ||
2338 AddrSpace == AMDGPUAS::BUFFER_STRIDED_POINTER) {
2339 if (!Subtarget->hasRelaxedBufferOOBMode() &&
2340 Alignment < Align(PowerOf2Ceil(divideCeil(Size, 8))))
2341 return false;
2342 }
2343
2344 // Smaller than dword value must be aligned.
2345 if (Size < 32)
2346 return false;
2347
2348 // 8.1.6 - For Dword or larger reads or writes, the two LSBs of the
2349 // byte-address are ignored, thus forcing Dword alignment.
2350 // This applies to private, global, and constant memory.
2351 if (IsFast)
2352 *IsFast = 1;
2353
2354 return Size >= 32 && Alignment >= Align(4);
2355}
2356
2358 EVT VT, unsigned AddrSpace, Align Alignment, MachineMemOperand::Flags Flags,
2359 unsigned *IsFast) const {
2361 Alignment, Flags, IsFast);
2362}
2363
2365 LLVMContext &Context, const MemOp &Op,
2366 const AttributeList &FuncAttributes) const {
2367 // FIXME: Should account for address space here.
2368
2369 // The default fallback uses the private pointer size as a guess for a type to
2370 // use. Make sure we switch these to 64-bit accesses.
2371
2372 if (Op.size() >= 16 &&
2373 Op.isDstAligned(Align(4))) // XXX: Should only do for global
2374 return MVT::v4i32;
2375
2376 if (Op.size() >= 8 && Op.isDstAligned(Align(4)))
2377 return MVT::v2i32;
2378
2379 // Use the default.
2380 return MVT::Other;
2381}
2382
2384 const MemSDNode *MemNode = cast<MemSDNode>(N);
2385 return MemNode->getMemOperand()->getFlags() & MONoClobber;
2386}
2387
2392
2394 unsigned DestAS) const {
2395 if (SrcAS == AMDGPUAS::FLAT_ADDRESS) {
2396 if (DestAS == AMDGPUAS::PRIVATE_ADDRESS &&
2397 Subtarget->hasGloballyAddressableScratch()) {
2398 // Flat -> private requires subtracting src_flat_scratch_base_lo.
2399 return false;
2400 }
2401
2402 // Flat -> private/local is a simple truncate.
2403 // Flat -> global is no-op
2404 return true;
2405 }
2406
2407 const GCNTargetMachine &TM =
2408 static_cast<const GCNTargetMachine &>(getTargetMachine());
2409 return TM.isNoopAddrSpaceCast(SrcAS, DestAS);
2410}
2411
2419
2421 Type *Ty) const {
2422 // FIXME: Could be smarter if called for vector constants.
2423 return true;
2424}
2425
2428 unsigned Index) const {
2431
2432 // TODO: Add more cases that are cheap.
2433 if (Index == 0)
2436}
2437
2438bool SITargetLowering::isExtractVecEltCheap(EVT VT, unsigned Index) const {
2439 // TODO: This should be more aggressive, particular for 16-bit element
2440 // vectors. However there are some mixed improvements and regressions.
2441 EVT EltTy = VT.getVectorElementType();
2442 unsigned MinAlign = Subtarget->useRealTrue16Insts() ? 16 : 32;
2443 return EltTy.getSizeInBits() % MinAlign == 0;
2444}
2445
2447 if (Subtarget->has16BitInsts() && VT == MVT::i16) {
2448 switch (Op) {
2449 case ISD::LOAD:
2450 case ISD::STORE:
2451 return true;
2452 default:
2453 return false;
2454 }
2455 }
2456
2457 // SimplifySetCC uses this function to determine whether or not it should
2458 // create setcc with i1 operands. We don't have instructions for i1 setcc.
2459 if (VT == MVT::i1 && Op == ISD::SETCC)
2460 return false;
2461
2463}
2464
2467 // This isn't really a constant pool but close enough.
2470 return PtrInfo;
2471}
2472
2473SDValue SITargetLowering::lowerKernArgParameterPtr(SelectionDAG &DAG,
2474 const SDLoc &SL,
2475 SDValue Chain,
2476 uint64_t Offset) const {
2477 const DataLayout &DL = DAG.getDataLayout();
2481
2482 auto [InputPtrReg, RC, ArgTy] =
2483 Info->getPreloadedValue(AMDGPUFunctionArgInfo::KERNARG_SEGMENT_PTR);
2484
2485 // We may not have the kernarg segment argument if we have no kernel
2486 // arguments.
2487 if (!InputPtrReg)
2488 return DAG.getConstant(Offset, SL, PtrVT);
2489
2491 SDValue BasePtr = DAG.getCopyFromReg(
2492 Chain, SL, MRI.getLiveInVirtReg(InputPtrReg->getRegister()), PtrVT);
2493
2494 return DAG.getObjectPtrOffset(SL, BasePtr, TypeSize::getFixed(Offset));
2495}
2496
2497SDValue SITargetLowering::getImplicitArgPtr(SelectionDAG &DAG,
2498 const SDLoc &SL) const {
2501 return lowerKernArgParameterPtr(DAG, SL, DAG.getEntryNode(), Offset);
2502}
2503
2504SDValue SITargetLowering::getLDSKernelId(SelectionDAG &DAG,
2505 const SDLoc &SL) const {
2506
2508 std::optional<uint32_t> KnownSize =
2510 if (KnownSize.has_value())
2511 return DAG.getConstant(*KnownSize, SL, MVT::i32);
2512 return SDValue();
2513}
2514
2515SDValue SITargetLowering::convertArgType(SelectionDAG &DAG, EVT VT, EVT MemVT,
2516 const SDLoc &SL, SDValue Val,
2517 bool Signed,
2518 const ISD::InputArg *Arg) const {
2519 // First, if it is a widened vector, narrow it.
2520 if (VT.isVector() &&
2522 EVT NarrowedVT =
2525 Val = DAG.getNode(ISD::EXTRACT_SUBVECTOR, SL, NarrowedVT, Val,
2526 DAG.getConstant(0, SL, MVT::i32));
2527 }
2528
2529 // Then convert the vector elements or scalar value.
2530 if (Arg && (Arg->Flags.isSExt() || Arg->Flags.isZExt()) && VT.bitsLT(MemVT)) {
2531 unsigned Opc = Arg->Flags.isZExt() ? ISD::AssertZext : ISD::AssertSext;
2532 Val = DAG.getNode(Opc, SL, MemVT, Val, DAG.getValueType(VT));
2533 }
2534
2535 if (MemVT.isFloatingPoint()) {
2536 if (VT.isFloatingPoint()) {
2537 Val = getFPExtOrFPRound(DAG, Val, SL, VT);
2538 } else {
2539 assert(!MemVT.isVector());
2540 EVT IntVT = EVT::getIntegerVT(*DAG.getContext(), MemVT.getSizeInBits());
2541 SDValue Cast = DAG.getBitcast(IntVT, Val);
2542 Val = DAG.getAnyExtOrTrunc(Cast, SL, VT);
2543 }
2544 } else if (Signed)
2545 Val = DAG.getSExtOrTrunc(Val, SL, VT);
2546 else
2547 Val = DAG.getZExtOrTrunc(Val, SL, VT);
2548
2549 return Val;
2550}
2551
2552SDValue SITargetLowering::lowerKernargMemParameter(
2553 SelectionDAG &DAG, EVT VT, EVT MemVT, const SDLoc &SL, SDValue Chain,
2554 uint64_t Offset, Align Alignment, bool Signed,
2555 const ISD::InputArg *Arg) const {
2556
2557 MachinePointerInfo PtrInfo =
2559
2560 // Try to avoid using an extload by loading earlier than the argument address,
2561 // and extracting the relevant bits. The load should hopefully be merged with
2562 // the previous argument.
2563 if (MemVT.getStoreSize() < 4 && Alignment < 4) {
2564 // TODO: Handle align < 4 and size >= 4 (can happen with packed structs).
2565 int64_t AlignDownOffset = alignDown(Offset, 4);
2566 int64_t OffsetDiff = Offset - AlignDownOffset;
2567
2568 EVT IntVT = MemVT.changeTypeToInteger();
2569
2570 // TODO: If we passed in the base kernel offset we could have a better
2571 // alignment than 4, but we don't really need it.
2572 SDValue Ptr = lowerKernArgParameterPtr(DAG, SL, Chain, AlignDownOffset);
2573 SDValue Load = DAG.getLoad(MVT::i32, SL, Chain, Ptr,
2574 PtrInfo.getWithOffset(AlignDownOffset), Align(4),
2577
2578 SDValue ShiftAmt = DAG.getConstant(OffsetDiff * 8, SL, MVT::i32);
2579 SDValue Extract = DAG.getNode(ISD::SRL, SL, MVT::i32, Load, ShiftAmt);
2580
2581 SDValue ArgVal = DAG.getNode(ISD::TRUNCATE, SL, IntVT, Extract);
2582 ArgVal = DAG.getNode(ISD::BITCAST, SL, MemVT, ArgVal);
2583 ArgVal = convertArgType(DAG, VT, MemVT, SL, ArgVal, Signed, Arg);
2584
2585 return DAG.getMergeValues({ArgVal, Load.getValue(1)}, SL);
2586 }
2587
2588 SDValue Ptr = lowerKernArgParameterPtr(DAG, SL, Chain, Offset);
2589 SDValue Load = DAG.getLoad(
2590 MemVT, SL, Chain, Ptr, PtrInfo.getWithOffset(Offset), Alignment,
2592
2593 SDValue Val = convertArgType(DAG, VT, MemVT, SL, Load, Signed, Arg);
2594 return DAG.getMergeValues({Val, Load.getValue(1)}, SL);
2595}
2596
2597/// Coerce an argument which was passed in a different ABI type to the original
2598/// expected value type.
2599SDValue SITargetLowering::convertABITypeToValueType(SelectionDAG &DAG,
2600 SDValue Val,
2601 CCValAssign &VA,
2602 const SDLoc &SL) const {
2603 EVT ValVT = VA.getValVT();
2604
2605 // If this is an 8 or 16-bit value, it is really passed promoted
2606 // to 32 bits. Insert an assert[sz]ext to capture this, then
2607 // truncate to the right size.
2608 switch (VA.getLocInfo()) {
2609 case CCValAssign::Full:
2610 return Val;
2611 case CCValAssign::BCvt:
2612 return DAG.getNode(ISD::BITCAST, SL, ValVT, Val);
2613 case CCValAssign::SExt:
2614 Val = DAG.getNode(ISD::AssertSext, SL, VA.getLocVT(), Val,
2615 DAG.getValueType(ValVT));
2616 return DAG.getNode(ISD::TRUNCATE, SL, ValVT, Val);
2617 case CCValAssign::ZExt:
2618 Val = DAG.getNode(ISD::AssertZext, SL, VA.getLocVT(), Val,
2619 DAG.getValueType(ValVT));
2620 return DAG.getNode(ISD::TRUNCATE, SL, ValVT, Val);
2621 case CCValAssign::AExt:
2622 return DAG.getNode(ISD::TRUNCATE, SL, ValVT, Val);
2623 default:
2624 llvm_unreachable("Unknown loc info!");
2625 }
2626}
2627
2628SDValue SITargetLowering::lowerStackParameter(SelectionDAG &DAG,
2629 CCValAssign &VA, const SDLoc &SL,
2630 SDValue Chain,
2631 const ISD::InputArg &Arg) const {
2633 MachineFrameInfo &MFI = MF.getFrameInfo();
2634
2635 if (Arg.Flags.isByVal()) {
2636 unsigned Size = Arg.Flags.getByValSize();
2637 int FrameIdx = MFI.CreateFixedObject(Size, VA.getLocMemOffset(), false);
2638 return DAG.getFrameIndex(FrameIdx, MVT::i32);
2639 }
2640
2641 unsigned ArgOffset = VA.getLocMemOffset();
2642 unsigned ArgSize = VA.getValVT().getStoreSize();
2643
2644 int FI = MFI.CreateFixedObject(ArgSize, ArgOffset, true);
2645
2646 // Create load nodes to retrieve arguments from the stack.
2647 SDValue FIN = DAG.getFrameIndex(FI, MVT::i32);
2648
2649 // For NON_EXTLOAD, generic code in getLoad assert(ValVT == MemVT)
2651 MVT MemVT = VA.getValVT();
2652
2653 switch (VA.getLocInfo()) {
2654 default:
2655 break;
2656 case CCValAssign::BCvt:
2657 MemVT = VA.getLocVT();
2658 break;
2659 case CCValAssign::SExt:
2660 ExtType = ISD::SEXTLOAD;
2661 break;
2662 case CCValAssign::ZExt:
2663 ExtType = ISD::ZEXTLOAD;
2664 break;
2665 case CCValAssign::AExt:
2666 ExtType = ISD::EXTLOAD;
2667 break;
2668 }
2669
2670 SDValue ArgValue = DAG.getExtLoad(
2671 ExtType, SL, VA.getLocVT(), Chain, FIN,
2673
2674 SDValue ConvertedVal = convertABITypeToValueType(DAG, ArgValue, VA, SL);
2675 if (ConvertedVal == ArgValue)
2676 return ConvertedVal;
2677
2678 return DAG.getMergeValues({ConvertedVal, ArgValue.getValue(1)}, SL);
2679}
2680
2681SDValue SITargetLowering::lowerWorkGroupId(
2682 SelectionDAG &DAG, const SIMachineFunctionInfo &MFI, EVT VT,
2685 AMDGPUFunctionArgInfo::PreloadedValue ClusterWorkGroupIdPV) const {
2686 if (!Subtarget->hasClusters())
2687 return getPreloadedValue(DAG, MFI, VT, WorkGroupIdPV);
2688
2689 // Clusters are supported. Return the global position in the grid. If clusters
2690 // are enabled, WorkGroupIdPV returns the cluster ID not the workgroup ID.
2691
2692 // WorkGroupIdXYZ = ClusterId == 0 ?
2693 // ClusterIdXYZ :
2694 // ClusterIdXYZ * (ClusterMaxIdXYZ + 1) + ClusterWorkGroupIdXYZ
2695 SDValue ClusterIdXYZ = getPreloadedValue(DAG, MFI, VT, WorkGroupIdPV);
2696 SDLoc SL(ClusterIdXYZ);
2697 SDValue ClusterMaxIdXYZ = getPreloadedValue(DAG, MFI, VT, ClusterMaxIdPV);
2698 SDValue One = DAG.getConstant(1, SL, VT);
2699 SDValue ClusterSizeXYZ = DAG.getNode(ISD::ADD, SL, VT, ClusterMaxIdXYZ, One);
2700 SDValue ClusterWorkGroupIdXYZ =
2701 getPreloadedValue(DAG, MFI, VT, ClusterWorkGroupIdPV);
2702 SDValue GlobalIdXYZ =
2703 DAG.getNode(ISD::ADD, SL, VT, ClusterWorkGroupIdXYZ,
2704 DAG.getNode(ISD::MUL, SL, VT, ClusterIdXYZ, ClusterSizeXYZ));
2705
2706 switch (MFI.getClusterDims().getKind()) {
2709 return GlobalIdXYZ;
2711 return ClusterIdXYZ;
2713 using namespace AMDGPU::Hwreg;
2714 SDValue ClusterIdField =
2715 DAG.getTargetConstant(HwregEncoding::encode(ID_IB_STS2, 6, 4), SL, VT);
2716 SDNode *GetReg =
2717 DAG.getMachineNode(AMDGPU::S_GETREG_B32_const, SL, VT, ClusterIdField);
2718 SDValue ClusterId(GetReg, 0);
2719 SDValue Zero = DAG.getConstant(0, SL, VT);
2720 return DAG.getNode(ISD::SELECT_CC, SL, VT, ClusterId, Zero, ClusterIdXYZ,
2721 GlobalIdXYZ, DAG.getCondCode(ISD::SETEQ));
2722 }
2723 }
2724
2725 llvm_unreachable("nothing should reach here");
2726}
2727
2728SDValue SITargetLowering::getPreloadedValue(
2729 SelectionDAG &DAG, const SIMachineFunctionInfo &MFI, EVT VT,
2731 const ArgDescriptor *Reg = nullptr;
2732 const TargetRegisterClass *RC = nullptr;
2733 LLT Ty;
2734
2736 const ArgDescriptor WorkGroupIDX =
2737 ArgDescriptor::createRegister(AMDGPU::TTMP9);
2738 // If GridZ is not programmed in an entry function then the hardware will set
2739 // it to all zeros, so there is no need to mask the GridY value in the low
2740 // order bits.
2741 const ArgDescriptor WorkGroupIDY = ArgDescriptor::createRegister(
2742 AMDGPU::TTMP7,
2743 AMDGPU::isEntryFunctionCC(CC) && !MFI.hasWorkGroupIDZ() ? ~0u : 0xFFFFu);
2744 const ArgDescriptor WorkGroupIDZ =
2745 ArgDescriptor::createRegister(AMDGPU::TTMP7, 0xFFFF0000u);
2746 const ArgDescriptor ClusterWorkGroupIDX =
2747 ArgDescriptor::createRegister(AMDGPU::TTMP6, 0x0000000Fu);
2748 const ArgDescriptor ClusterWorkGroupIDY =
2749 ArgDescriptor::createRegister(AMDGPU::TTMP6, 0x000000F0u);
2750 const ArgDescriptor ClusterWorkGroupIDZ =
2751 ArgDescriptor::createRegister(AMDGPU::TTMP6, 0x00000F00u);
2752 const ArgDescriptor ClusterWorkGroupMaxIDX =
2753 ArgDescriptor::createRegister(AMDGPU::TTMP6, 0x0000F000u);
2754 const ArgDescriptor ClusterWorkGroupMaxIDY =
2755 ArgDescriptor::createRegister(AMDGPU::TTMP6, 0x000F0000u);
2756 const ArgDescriptor ClusterWorkGroupMaxIDZ =
2757 ArgDescriptor::createRegister(AMDGPU::TTMP6, 0x00F00000u);
2758 const ArgDescriptor ClusterWorkGroupMaxFlatID =
2759 ArgDescriptor::createRegister(AMDGPU::TTMP6, 0x0F000000u);
2760
2761 auto LoadConstant = [&](unsigned N) {
2762 return DAG.getConstant(N, SDLoc(), VT);
2763 };
2764
2765 if (Subtarget->hasArchitectedSGPRs() &&
2767 AMDGPU::ClusterDimsAttr ClusterDims = MFI.getClusterDims();
2768 bool HasFixedDims = ClusterDims.isFixedDims();
2769
2770 switch (PVID) {
2772 Reg = &WorkGroupIDX;
2773 RC = &AMDGPU::SReg_32RegClass;
2774 Ty = LLT::scalar(32);
2775 break;
2777 Reg = &WorkGroupIDY;
2778 RC = &AMDGPU::SReg_32RegClass;
2779 Ty = LLT::scalar(32);
2780 break;
2782 Reg = &WorkGroupIDZ;
2783 RC = &AMDGPU::SReg_32RegClass;
2784 Ty = LLT::scalar(32);
2785 break;
2787 if (HasFixedDims && ClusterDims.getDims()[0] == 1)
2788 return LoadConstant(0);
2789 Reg = &ClusterWorkGroupIDX;
2790 RC = &AMDGPU::SReg_32RegClass;
2791 Ty = LLT::scalar(32);
2792 break;
2794 if (HasFixedDims && ClusterDims.getDims()[1] == 1)
2795 return LoadConstant(0);
2796 Reg = &ClusterWorkGroupIDY;
2797 RC = &AMDGPU::SReg_32RegClass;
2798 Ty = LLT::scalar(32);
2799 break;
2801 if (HasFixedDims && ClusterDims.getDims()[2] == 1)
2802 return LoadConstant(0);
2803 Reg = &ClusterWorkGroupIDZ;
2804 RC = &AMDGPU::SReg_32RegClass;
2805 Ty = LLT::scalar(32);
2806 break;
2808 if (HasFixedDims)
2809 return LoadConstant(ClusterDims.getDims()[0] - 1);
2810 Reg = &ClusterWorkGroupMaxIDX;
2811 RC = &AMDGPU::SReg_32RegClass;
2812 Ty = LLT::scalar(32);
2813 break;
2815 if (HasFixedDims)
2816 return LoadConstant(ClusterDims.getDims()[1] - 1);
2817 Reg = &ClusterWorkGroupMaxIDY;
2818 RC = &AMDGPU::SReg_32RegClass;
2819 Ty = LLT::scalar(32);
2820 break;
2822 if (HasFixedDims)
2823 return LoadConstant(ClusterDims.getDims()[2] - 1);
2824 Reg = &ClusterWorkGroupMaxIDZ;
2825 RC = &AMDGPU::SReg_32RegClass;
2826 Ty = LLT::scalar(32);
2827 break;
2829 Reg = &ClusterWorkGroupMaxFlatID;
2830 RC = &AMDGPU::SReg_32RegClass;
2831 Ty = LLT::scalar(32);
2832 break;
2833 default:
2834 break;
2835 }
2836 }
2837
2838 if (!Reg)
2839 std::tie(Reg, RC, Ty) = MFI.getPreloadedValue(PVID);
2840 if (!Reg) {
2842 // It's possible for a kernarg intrinsic call to appear in a kernel with
2843 // no allocated segment, in which case we do not add the user sgpr
2844 // argument, so just return null.
2845 return DAG.getConstant(0, SDLoc(), VT);
2846 }
2847
2848 // It's undefined behavior if a function marked with the amdgpu-no-*
2849 // attributes uses the corresponding intrinsic.
2850 return DAG.getPOISON(VT);
2851 }
2852
2853 return loadInputValue(DAG, RC, VT, SDLoc(DAG.getEntryNode()), *Reg);
2854}
2855
2857 CallingConv::ID CallConv,
2858 ArrayRef<ISD::InputArg> Ins, BitVector &Skipped,
2859 FunctionType *FType,
2860 SIMachineFunctionInfo *Info) {
2861 for (unsigned I = 0, E = Ins.size(), PSInputNum = 0; I != E; ++I) {
2862 const ISD::InputArg *Arg = &Ins[I];
2863
2864 assert((!Arg->VT.isVector() || Arg->VT.getScalarSizeInBits() == 16) &&
2865 "vector type argument should have been split");
2866
2867 // First check if it's a PS input addr.
2868 if (CallConv == CallingConv::AMDGPU_PS && !Arg->Flags.isInReg() &&
2869 PSInputNum <= 15) {
2870 bool SkipArg = !Arg->Used && !Info->isPSInputAllocated(PSInputNum);
2871
2872 // Inconveniently only the first part of the split is marked as isSplit,
2873 // so skip to the end. We only want to increment PSInputNum once for the
2874 // entire split argument.
2875 if (Arg->Flags.isSplit()) {
2876 while (!Arg->Flags.isSplitEnd()) {
2877 assert((!Arg->VT.isVector() || Arg->VT.getScalarSizeInBits() == 16) &&
2878 "unexpected vector split in ps argument type");
2879 if (!SkipArg)
2880 Splits.push_back(*Arg);
2881 Arg = &Ins[++I];
2882 }
2883 }
2884
2885 if (SkipArg) {
2886 // We can safely skip PS inputs.
2887 Skipped.set(Arg->getOrigArgIndex());
2888 ++PSInputNum;
2889 continue;
2890 }
2891
2892 Info->markPSInputAllocated(PSInputNum);
2893 if (Arg->Used)
2894 Info->markPSInputEnabled(PSInputNum);
2895
2896 ++PSInputNum;
2897 }
2898
2899 Splits.push_back(*Arg);
2900 }
2901}
2902
2903// Allocate special inputs passed in VGPRs.
2905 CCState &CCInfo, MachineFunction &MF, const SIRegisterInfo &TRI,
2906 SIMachineFunctionInfo &Info) const {
2907 const LLT S32 = LLT::scalar(32);
2908 MachineRegisterInfo &MRI = MF.getRegInfo();
2909
2910 if (Info.hasWorkItemIDX()) {
2911 Register Reg = AMDGPU::VGPR0;
2912 MRI.setType(MF.addLiveIn(Reg, &AMDGPU::VGPR_32RegClass), S32);
2913
2914 CCInfo.AllocateReg(Reg);
2915 unsigned Mask =
2916 (Subtarget->hasPackedTID() && Info.hasWorkItemIDY()) ? 0x3ff : ~0u;
2917 Info.setWorkItemIDX(ArgDescriptor::createRegister(Reg, Mask));
2918 }
2919
2920 if (Info.hasWorkItemIDY()) {
2921 assert(Info.hasWorkItemIDX());
2922 if (Subtarget->hasPackedTID()) {
2923 Info.setWorkItemIDY(
2924 ArgDescriptor::createRegister(AMDGPU::VGPR0, 0x3ff << 10));
2925 } else {
2926 unsigned Reg = AMDGPU::VGPR1;
2927 MRI.setType(MF.addLiveIn(Reg, &AMDGPU::VGPR_32RegClass), S32);
2928
2929 CCInfo.AllocateReg(Reg);
2930 Info.setWorkItemIDY(ArgDescriptor::createRegister(Reg));
2931 }
2932 }
2933
2934 if (Info.hasWorkItemIDZ()) {
2935 assert(Info.hasWorkItemIDX() && Info.hasWorkItemIDY());
2936 if (Subtarget->hasPackedTID()) {
2937 Info.setWorkItemIDZ(
2938 ArgDescriptor::createRegister(AMDGPU::VGPR0, 0x3ff << 20));
2939 } else {
2940 unsigned Reg = AMDGPU::VGPR2;
2941 MRI.setType(MF.addLiveIn(Reg, &AMDGPU::VGPR_32RegClass), S32);
2942
2943 CCInfo.AllocateReg(Reg);
2944 Info.setWorkItemIDZ(ArgDescriptor::createRegister(Reg));
2945 }
2946 }
2947}
2948
2949// Try to allocate a VGPR at the end of the argument list, or if no argument
2950// VGPRs are left allocating a stack slot.
2951// If \p Mask is given it indicates bitfield position in the register.
2952// If \p Arg is given use it with new ]p Mask instead of allocating new.
2953static ArgDescriptor allocateVGPR32Input(CCState &CCInfo, unsigned Mask = ~0u,
2954 ArgDescriptor Arg = ArgDescriptor()) {
2955 if (Arg.isSet())
2956 return ArgDescriptor::createArg(Arg, Mask);
2957
2958 ArrayRef<MCPhysReg> ArgVGPRs = ArrayRef(AMDGPU::VGPR_32RegClass.begin(), 32);
2959 unsigned RegIdx = CCInfo.getFirstUnallocated(ArgVGPRs);
2960 if (RegIdx == ArgVGPRs.size()) {
2961 // Spill to stack required.
2962 int64_t Offset = CCInfo.AllocateStack(4, Align(4));
2963
2964 return ArgDescriptor::createStack(Offset, Mask);
2965 }
2966
2967 unsigned Reg = ArgVGPRs[RegIdx];
2968 Reg = CCInfo.AllocateReg(Reg);
2969 assert(Reg != AMDGPU::NoRegister);
2970
2971 MachineFunction &MF = CCInfo.getMachineFunction();
2972 Register LiveInVReg = MF.addLiveIn(Reg, &AMDGPU::VGPR_32RegClass);
2973 MF.getRegInfo().setType(LiveInVReg, LLT::scalar(32));
2974 return ArgDescriptor::createRegister(Reg, Mask);
2975}
2976
2978 const TargetRegisterClass *RC,
2979 unsigned NumArgRegs) {
2980 ArrayRef<MCPhysReg> ArgSGPRs = ArrayRef(RC->begin(), 32);
2981 unsigned RegIdx = CCInfo.getFirstUnallocated(ArgSGPRs);
2982 if (RegIdx == ArgSGPRs.size())
2983 report_fatal_error("ran out of SGPRs for arguments");
2984
2985 unsigned Reg = ArgSGPRs[RegIdx];
2986 Reg = CCInfo.AllocateReg(Reg);
2987 assert(Reg != AMDGPU::NoRegister);
2988
2989 MachineFunction &MF = CCInfo.getMachineFunction();
2990 MF.addLiveIn(Reg, RC);
2992}
2993
2994// If this has a fixed position, we still should allocate the register in the
2995// CCInfo state. Technically we could get away with this for values passed
2996// outside of the normal argument range.
2998 const TargetRegisterClass *RC,
2999 MCRegister Reg) {
3000 Reg = CCInfo.AllocateReg(Reg);
3001 assert(Reg != AMDGPU::NoRegister);
3002 MachineFunction &MF = CCInfo.getMachineFunction();
3003 MF.addLiveIn(Reg, RC);
3004}
3005
3006static void allocateSGPR32Input(CCState &CCInfo, ArgDescriptor &Arg) {
3007 if (Arg) {
3008 allocateFixedSGPRInputImpl(CCInfo, &AMDGPU::SGPR_32RegClass,
3009 Arg.getRegister());
3010 } else
3011 Arg = allocateSGPR32InputImpl(CCInfo, &AMDGPU::SGPR_32RegClass, 32);
3012}
3013
3014static void allocateSGPR64Input(CCState &CCInfo, ArgDescriptor &Arg) {
3015 if (Arg) {
3016 allocateFixedSGPRInputImpl(CCInfo, &AMDGPU::SGPR_64RegClass,
3017 Arg.getRegister());
3018 } else
3019 Arg = allocateSGPR32InputImpl(CCInfo, &AMDGPU::SGPR_64RegClass, 16);
3020}
3021
3022/// Allocate implicit function VGPR arguments at the end of allocated user
3023/// arguments.
3025 CCState &CCInfo, MachineFunction &MF, const SIRegisterInfo &TRI,
3026 SIMachineFunctionInfo &Info) const {
3027 const unsigned Mask = 0x3ff;
3028 ArgDescriptor Arg;
3029
3030 if (Info.hasWorkItemIDX()) {
3031 Arg = allocateVGPR32Input(CCInfo, Mask);
3032 Info.setWorkItemIDX(Arg);
3033 }
3034
3035 if (Info.hasWorkItemIDY()) {
3036 Arg = allocateVGPR32Input(CCInfo, Mask << 10, Arg);
3037 Info.setWorkItemIDY(Arg);
3038 }
3039
3040 if (Info.hasWorkItemIDZ())
3041 Info.setWorkItemIDZ(allocateVGPR32Input(CCInfo, Mask << 20, Arg));
3042}
3043
3044/// Allocate implicit function VGPR arguments in fixed registers.
3046 CCState &CCInfo, MachineFunction &MF, const SIRegisterInfo &TRI,
3047 SIMachineFunctionInfo &Info) const {
3048 Register Reg = CCInfo.AllocateReg(AMDGPU::VGPR31);
3049 if (!Reg)
3050 report_fatal_error("failed to allocate VGPR for implicit arguments");
3051
3052 const unsigned Mask = 0x3ff;
3053 Info.setWorkItemIDX(ArgDescriptor::createRegister(Reg, Mask));
3054 Info.setWorkItemIDY(ArgDescriptor::createRegister(Reg, Mask << 10));
3055 Info.setWorkItemIDZ(ArgDescriptor::createRegister(Reg, Mask << 20));
3056}
3057
3059 CCState &CCInfo, MachineFunction &MF, const SIRegisterInfo &TRI,
3060 SIMachineFunctionInfo &Info) const {
3061 auto &ArgInfo = Info.getArgInfo();
3062 const GCNUserSGPRUsageInfo &UserSGPRInfo = Info.getUserSGPRInfo();
3063
3064 // TODO: Unify handling with private memory pointers.
3065 if (UserSGPRInfo.hasDispatchPtr())
3066 allocateSGPR64Input(CCInfo, ArgInfo.DispatchPtr);
3067
3068 if (UserSGPRInfo.hasQueuePtr())
3069 allocateSGPR64Input(CCInfo, ArgInfo.QueuePtr);
3070
3071 // Implicit arg ptr takes the place of the kernarg segment pointer. This is a
3072 // constant offset from the kernarg segment.
3073 if (Info.hasImplicitArgPtr())
3074 allocateSGPR64Input(CCInfo, ArgInfo.ImplicitArgPtr);
3075
3076 if (UserSGPRInfo.hasDispatchID())
3077 allocateSGPR64Input(CCInfo, ArgInfo.DispatchID);
3078
3079 // flat_scratch_init is not applicable for non-kernel functions.
3080
3081 if (Info.hasWorkGroupIDX())
3082 allocateSGPR32Input(CCInfo, ArgInfo.WorkGroupIDX);
3083
3084 if (Info.hasWorkGroupIDY())
3085 allocateSGPR32Input(CCInfo, ArgInfo.WorkGroupIDY);
3086
3087 if (Info.hasWorkGroupIDZ())
3088 allocateSGPR32Input(CCInfo, ArgInfo.WorkGroupIDZ);
3089
3090 if (Info.hasLDSKernelId())
3091 allocateSGPR32Input(CCInfo, ArgInfo.LDSKernelId);
3092}
3093
3094// Allocate special inputs passed in user SGPRs.
3096 MachineFunction &MF,
3097 const SIRegisterInfo &TRI,
3098 SIMachineFunctionInfo &Info) const {
3099 const GCNUserSGPRUsageInfo &UserSGPRInfo = Info.getUserSGPRInfo();
3100 if (UserSGPRInfo.hasImplicitBufferPtr()) {
3101 Register ImplicitBufferPtrReg = Info.addImplicitBufferPtr(TRI);
3102 MF.addLiveIn(ImplicitBufferPtrReg, &AMDGPU::SGPR_64RegClass);
3103 CCInfo.AllocateReg(ImplicitBufferPtrReg);
3104 }
3105
3106 // FIXME: How should these inputs interact with inreg / custom SGPR inputs?
3107 if (UserSGPRInfo.hasPrivateSegmentBuffer()) {
3108 Register PrivateSegmentBufferReg = Info.addPrivateSegmentBuffer(TRI);
3109 MF.addLiveIn(PrivateSegmentBufferReg, &AMDGPU::SGPR_128RegClass);
3110 CCInfo.AllocateReg(PrivateSegmentBufferReg);
3111 }
3112
3113 if (UserSGPRInfo.hasDispatchPtr()) {
3114 Register DispatchPtrReg = Info.addDispatchPtr(TRI);
3115 MF.addLiveIn(DispatchPtrReg, &AMDGPU::SGPR_64RegClass);
3116 CCInfo.AllocateReg(DispatchPtrReg);
3117 }
3118
3119 if (UserSGPRInfo.hasQueuePtr()) {
3120 Register QueuePtrReg = Info.addQueuePtr(TRI);
3121 MF.addLiveIn(QueuePtrReg, &AMDGPU::SGPR_64RegClass);
3122 CCInfo.AllocateReg(QueuePtrReg);
3123 }
3124
3125 if (UserSGPRInfo.hasKernargSegmentPtr()) {
3126 MachineRegisterInfo &MRI = MF.getRegInfo();
3127 Register InputPtrReg = Info.addKernargSegmentPtr(TRI);
3128 CCInfo.AllocateReg(InputPtrReg);
3129
3130 Register VReg = MF.addLiveIn(InputPtrReg, &AMDGPU::SGPR_64RegClass);
3132 }
3133
3134 if (UserSGPRInfo.hasDispatchID()) {
3135 Register DispatchIDReg = Info.addDispatchID(TRI);
3136 MF.addLiveIn(DispatchIDReg, &AMDGPU::SGPR_64RegClass);
3137 CCInfo.AllocateReg(DispatchIDReg);
3138 }
3139
3140 if (UserSGPRInfo.hasFlatScratchInit() && !getSubtarget()->isAmdPalOS()) {
3141 Register FlatScratchInitReg = Info.addFlatScratchInit(TRI);
3142 MF.addLiveIn(FlatScratchInitReg, &AMDGPU::SGPR_64RegClass);
3143 CCInfo.AllocateReg(FlatScratchInitReg);
3144 }
3145
3146 if (UserSGPRInfo.hasPrivateSegmentSize()) {
3147 Register PrivateSegmentSizeReg = Info.addPrivateSegmentSize(TRI);
3148 MF.addLiveIn(PrivateSegmentSizeReg, &AMDGPU::SGPR_32RegClass);
3149 CCInfo.AllocateReg(PrivateSegmentSizeReg);
3150 }
3151
3152 // TODO: Add GridWorkGroupCount user SGPRs when used. For now with HSA we read
3153 // these from the dispatch pointer.
3154}
3155
3156// Allocate pre-loaded kernel arguemtns. Arguments to be preloading must be
3157// sequential starting from the first argument.
3159 CCState &CCInfo, SmallVectorImpl<CCValAssign> &ArgLocs,
3161 const SIRegisterInfo &TRI, SIMachineFunctionInfo &Info) const {
3162 Function &F = MF.getFunction();
3163 unsigned LastExplicitArgOffset = Subtarget->getExplicitKernelArgOffset();
3164 GCNUserSGPRUsageInfo &SGPRInfo = Info.getUserSGPRInfo();
3165 bool InPreloadSequence = true;
3166 unsigned InIdx = 0;
3167 bool AlignedForImplictArgs = false;
3168 unsigned ImplicitArgOffset = 0;
3169 for (auto &Arg : F.args()) {
3170 if (!InPreloadSequence || !Arg.hasInRegAttr())
3171 break;
3172
3173 unsigned ArgIdx = Arg.getArgNo();
3174 // Don't preload non-original args or parts not in the current preload
3175 // sequence.
3176 if (InIdx < Ins.size() &&
3177 (!Ins[InIdx].isOrigArg() || Ins[InIdx].getOrigArgIndex() != ArgIdx))
3178 break;
3179
3180 for (; InIdx < Ins.size() && Ins[InIdx].isOrigArg() &&
3181 Ins[InIdx].getOrigArgIndex() == ArgIdx;
3182 InIdx++) {
3183 assert(ArgLocs[ArgIdx].isMemLoc());
3184 auto &ArgLoc = ArgLocs[InIdx];
3185 const Align KernelArgBaseAlign = Align(16);
3186 unsigned ArgOffset = ArgLoc.getLocMemOffset();
3187 Align Alignment = commonAlignment(KernelArgBaseAlign, ArgOffset);
3188 unsigned NumAllocSGPRs =
3189 alignTo(ArgLoc.getLocVT().getFixedSizeInBits(), 32) / 32;
3190
3191 // Fix alignment for hidden arguments.
3192 if (Arg.hasAttribute("amdgpu-hidden-argument")) {
3193 if (!AlignedForImplictArgs) {
3194 ImplicitArgOffset =
3195 alignTo(LastExplicitArgOffset,
3196 Subtarget->getAlignmentForImplicitArgPtr()) -
3197 LastExplicitArgOffset;
3198 AlignedForImplictArgs = true;
3199 }
3200 ArgOffset += ImplicitArgOffset;
3201 }
3202
3203 // Arg is preloaded into the previous SGPR.
3204 if (ArgLoc.getLocVT().getStoreSize() < 4 && Alignment < 4) {
3205 assert(InIdx >= 1 && "No previous SGPR");
3206 Info.getArgInfo().PreloadKernArgs[InIdx].Regs.push_back(
3207 Info.getArgInfo().PreloadKernArgs[InIdx - 1].Regs[0]);
3208 continue;
3209 }
3210
3211 unsigned Padding = ArgOffset - LastExplicitArgOffset;
3212 unsigned PaddingSGPRs = alignTo(Padding, 4) / 4;
3213 // Check for free user SGPRs for preloading.
3214 if (PaddingSGPRs + NumAllocSGPRs > SGPRInfo.getNumFreeUserSGPRs()) {
3215 InPreloadSequence = false;
3216 break;
3217 }
3218
3219 // Preload this argument.
3220 const TargetRegisterClass *RC =
3221 TRI.getSGPRClassForBitWidth(NumAllocSGPRs * 32);
3222 SmallVectorImpl<MCRegister> *PreloadRegs =
3223 Info.addPreloadedKernArg(TRI, RC, NumAllocSGPRs, InIdx, PaddingSGPRs);
3224
3225 if (PreloadRegs->size() > 1)
3226 RC = &AMDGPU::SGPR_32RegClass;
3227 for (auto &Reg : *PreloadRegs) {
3228 assert(Reg);
3229 MF.addLiveIn(Reg, RC);
3230 CCInfo.AllocateReg(Reg);
3231 }
3232
3233 LastExplicitArgOffset = NumAllocSGPRs * 4 + ArgOffset;
3234 }
3235 }
3236}
3237
3239 const SIRegisterInfo &TRI,
3240 SIMachineFunctionInfo &Info) const {
3241 // Always allocate this last since it is a synthetic preload.
3242 if (Info.hasLDSKernelId()) {
3243 Register Reg = Info.addLDSKernelId();
3244 MF.addLiveIn(Reg, &AMDGPU::SGPR_32RegClass);
3245 CCInfo.AllocateReg(Reg);
3246 }
3247}
3248
3249// Allocate special input registers that are initialized per-wave.
3252 CallingConv::ID CallConv,
3253 bool IsShader) const {
3254 bool HasArchitectedSGPRs = Subtarget->hasArchitectedSGPRs();
3255 if (Subtarget->hasUserSGPRInit16BugInWave32() && !IsShader) {
3256 // Note: user SGPRs are handled by the front-end for graphics shaders
3257 // Pad up the used user SGPRs with dead inputs.
3258
3259 // TODO: NumRequiredSystemSGPRs computation should be adjusted appropriately
3260 // before enabling architected SGPRs for workgroup IDs.
3261 assert(!HasArchitectedSGPRs && "Unhandled feature for the subtarget");
3262
3263 unsigned CurrentUserSGPRs = Info.getNumUserSGPRs();
3264 // Note we do not count the PrivateSegmentWaveByteOffset. We do not want to
3265 // rely on it to reach 16 since if we end up having no stack usage, it will
3266 // not really be added.
3267 unsigned NumRequiredSystemSGPRs =
3268 Info.hasWorkGroupIDX() + Info.hasWorkGroupIDY() +
3269 Info.hasWorkGroupIDZ() + Info.hasWorkGroupInfo();
3270 for (unsigned i = NumRequiredSystemSGPRs + CurrentUserSGPRs; i < 16; ++i) {
3271 Register Reg = Info.addReservedUserSGPR();
3272 MF.addLiveIn(Reg, &AMDGPU::SGPR_32RegClass);
3273 CCInfo.AllocateReg(Reg);
3274 }
3275 }
3276
3277 if (!HasArchitectedSGPRs) {
3278 if (Info.hasWorkGroupIDX()) {
3279 Register Reg = Info.addWorkGroupIDX();
3280 MF.addLiveIn(Reg, &AMDGPU::SGPR_32RegClass);
3281 CCInfo.AllocateReg(Reg);
3282 }
3283
3284 if (Info.hasWorkGroupIDY()) {
3285 Register Reg = Info.addWorkGroupIDY();
3286 MF.addLiveIn(Reg, &AMDGPU::SGPR_32RegClass);
3287 CCInfo.AllocateReg(Reg);
3288 }
3289
3290 if (Info.hasWorkGroupIDZ()) {
3291 Register Reg = Info.addWorkGroupIDZ();
3292 MF.addLiveIn(Reg, &AMDGPU::SGPR_32RegClass);
3293 CCInfo.AllocateReg(Reg);
3294 }
3295 }
3296
3297 if (Info.hasWorkGroupInfo()) {
3298 Register Reg = Info.addWorkGroupInfo();
3299 MF.addLiveIn(Reg, &AMDGPU::SGPR_32RegClass);
3300 CCInfo.AllocateReg(Reg);
3301 }
3302
3303 if (Info.hasPrivateSegmentWaveByteOffset()) {
3304 // Scratch wave offset passed in system SGPR.
3305 unsigned PrivateSegmentWaveByteOffsetReg;
3306
3307 if (IsShader) {
3308 PrivateSegmentWaveByteOffsetReg =
3309 Info.getPrivateSegmentWaveByteOffsetSystemSGPR();
3310
3311 // This is true if the scratch wave byte offset doesn't have a fixed
3312 // location.
3313 if (PrivateSegmentWaveByteOffsetReg == AMDGPU::NoRegister) {
3314 PrivateSegmentWaveByteOffsetReg = findFirstFreeSGPR(CCInfo);
3315 Info.setPrivateSegmentWaveByteOffset(PrivateSegmentWaveByteOffsetReg);
3316 }
3317 } else
3318 PrivateSegmentWaveByteOffsetReg = Info.addPrivateSegmentWaveByteOffset();
3319
3320 MF.addLiveIn(PrivateSegmentWaveByteOffsetReg, &AMDGPU::SGPR_32RegClass);
3321 CCInfo.AllocateReg(PrivateSegmentWaveByteOffsetReg);
3322 }
3323
3324 assert(!Subtarget->hasUserSGPRInit16BugInWave32() || IsShader ||
3325 Info.getNumPreloadedSGPRs() >= 16);
3326}
3327
3329 MachineFunction &MF,
3330 const SIRegisterInfo &TRI,
3331 SIMachineFunctionInfo &Info) {
3332 // Now that we've figured out where the scratch register inputs are, see if
3333 // should reserve the arguments and use them directly.
3334 MachineFrameInfo &MFI = MF.getFrameInfo();
3335 bool HasStackObjects = MFI.hasStackObjects();
3336 const GCNSubtarget &ST = MF.getSubtarget<GCNSubtarget>();
3337
3338 // Record that we know we have non-spill stack objects so we don't need to
3339 // check all stack objects later.
3340 if (HasStackObjects)
3341 Info.setHasNonSpillStackObjects(true);
3342
3343 // Everything live out of a block is spilled with fast regalloc, so it's
3344 // almost certain that spilling will be required.
3346 HasStackObjects = true;
3347
3348 // For now assume stack access is needed in any callee functions, so we need
3349 // the scratch registers to pass in.
3350 bool RequiresStackAccess = HasStackObjects || MFI.hasCalls();
3351
3352 if (!ST.hasFlatScratchEnabled()) {
3353 if (RequiresStackAccess && ST.isAmdHsaOrMesa(MF.getFunction())) {
3354 // If we have stack objects, we unquestionably need the private buffer
3355 // resource. For the Code Object V2 ABI, this will be the first 4 user
3356 // SGPR inputs. We can reserve those and use them directly.
3357
3358 Register PrivateSegmentBufferReg =
3360 Info.setScratchRSrcReg(PrivateSegmentBufferReg);
3361 } else {
3362 unsigned ReservedBufferReg = TRI.reservedPrivateSegmentBufferReg(MF);
3363 // We tentatively reserve the last registers (skipping the last registers
3364 // which may contain VCC, FLAT_SCR, and XNACK). After register allocation,
3365 // we'll replace these with the ones immediately after those which were
3366 // really allocated. In the prologue copies will be inserted from the
3367 // argument to these reserved registers.
3368
3369 // Without HSA, relocations are used for the scratch pointer and the
3370 // buffer resource setup is always inserted in the prologue. Scratch wave
3371 // offset is still in an input SGPR.
3372 Info.setScratchRSrcReg(ReservedBufferReg);
3373 }
3374 }
3375
3376 MachineRegisterInfo &MRI = MF.getRegInfo();
3377
3378 // For entry functions we have to set up the stack pointer if we use it,
3379 // whereas non-entry functions get this "for free". This means there is no
3380 // intrinsic advantage to using S32 over S34 in cases where we do not have
3381 // calls but do need a frame pointer (i.e. if we are requested to have one
3382 // because frame pointer elimination is disabled). To keep things simple we
3383 // only ever use S32 as the call ABI stack pointer, and so using it does not
3384 // imply we need a separate frame pointer.
3385 //
3386 // Try to use s32 as the SP, but move it if it would interfere with input
3387 // arguments. This won't work with calls though.
3388 //
3389 // FIXME: Move SP to avoid any possible inputs, or find a way to spill input
3390 // registers.
3391 if (!MRI.isLiveIn(AMDGPU::SGPR32)) {
3392 Info.setStackPtrOffsetReg(AMDGPU::SGPR32);
3393 } else {
3395
3396 if (MFI.hasCalls())
3397 report_fatal_error("call in graphics shader with too many input SGPRs");
3398
3399 for (unsigned Reg : AMDGPU::SGPR_32RegClass) {
3400 if (!MRI.isLiveIn(Reg)) {
3401 Info.setStackPtrOffsetReg(Reg);
3402 break;
3403 }
3404 }
3405
3406 if (Info.getStackPtrOffsetReg() == AMDGPU::SP_REG)
3407 report_fatal_error("failed to find register for SP");
3408 }
3409
3410 // hasFP should be accurate for entry functions even before the frame is
3411 // finalized, because it does not rely on the known stack size, only
3412 // properties like whether variable sized objects are present.
3413 if (ST.getFrameLowering()->hasFP(MF)) {
3414 Info.setFrameOffsetReg(AMDGPU::SGPR33);
3415 }
3416}
3417
3420 return !Info->isEntryFunction();
3421}
3422
3424
3426 MachineBasicBlock *Entry,
3427 const SmallVectorImpl<MachineBasicBlock *> &Exits) const {
3429
3430 const MCPhysReg *IStart = TRI->getCalleeSavedRegsViaCopy(Entry->getParent());
3431 if (!IStart)
3432 return;
3433
3434 const TargetInstrInfo *TII = Subtarget->getInstrInfo();
3435 MachineRegisterInfo *MRI = &Entry->getParent()->getRegInfo();
3436 MachineBasicBlock::iterator MBBI = Entry->begin();
3437 for (const MCPhysReg *I = IStart; *I; ++I) {
3438 const TargetRegisterClass *RC = nullptr;
3439 if (AMDGPU::SReg_64RegClass.contains(*I))
3440 RC = &AMDGPU::SGPR_64RegClass;
3441 else if (AMDGPU::SReg_32RegClass.contains(*I))
3442 RC = &AMDGPU::SGPR_32RegClass;
3443 else
3444 llvm_unreachable("Unexpected register class in CSRsViaCopy!");
3445
3446 Register NewVR = MRI->createVirtualRegister(RC);
3447 // Create copy from CSR to a virtual register.
3448 Entry->addLiveIn(*I);
3449 BuildMI(*Entry, MBBI, DebugLoc(), TII->get(TargetOpcode::COPY), NewVR)
3450 .addReg(*I);
3451
3452 // Insert the copy-back instructions right before the terminator.
3453 for (auto *Exit : Exits)
3454 BuildMI(*Exit, Exit->getFirstTerminator(), DebugLoc(),
3455 TII->get(TargetOpcode::COPY), *I)
3456 .addReg(NewVR);
3457 }
3458}
3459
3461 SDValue Chain, CallingConv::ID CallConv, bool isVarArg,
3462 const SmallVectorImpl<ISD::InputArg> &Ins, const SDLoc &DL,
3463 SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals) const {
3465
3467 const Function &Fn = MF.getFunction();
3470 bool IsError = false;
3471
3472 if (Subtarget->isAmdHsaOS() && AMDGPU::isGraphics(CallConv)) {
3474 Fn, "unsupported non-compute shaders with HSA", DL.getDebugLoc()));
3475 IsError = true;
3476 }
3477
3480 BitVector Skipped(Fn.arg_size());
3481 CCState CCInfo(CallConv, isVarArg, DAG.getMachineFunction(), ArgLocs,
3482 *DAG.getContext());
3483
3484 bool IsGraphics = AMDGPU::isGraphics(CallConv);
3485 bool IsKernel = AMDGPU::isKernel(CallConv);
3486 bool IsEntryFunc = AMDGPU::isEntryFunctionCC(CallConv);
3487
3488 if (IsGraphics) {
3489 const GCNUserSGPRUsageInfo &UserSGPRInfo = Info->getUserSGPRInfo();
3490 assert(!UserSGPRInfo.hasDispatchPtr() &&
3491 !UserSGPRInfo.hasKernargSegmentPtr() && !Info->hasWorkGroupInfo() &&
3492 !Info->hasLDSKernelId() && !Info->hasWorkItemIDX() &&
3493 !Info->hasWorkItemIDY() && !Info->hasWorkItemIDZ());
3494 (void)UserSGPRInfo;
3495 if (!Subtarget->hasFlatScratchEnabled())
3496 assert(!UserSGPRInfo.hasFlatScratchInit());
3497 if ((CallConv != CallingConv::AMDGPU_CS &&
3498 CallConv != CallingConv::AMDGPU_Gfx &&
3499 CallConv != CallingConv::AMDGPU_Gfx_WholeWave) ||
3500 !Subtarget->hasArchitectedSGPRs())
3501 assert(!Info->hasWorkGroupIDX() && !Info->hasWorkGroupIDY() &&
3502 !Info->hasWorkGroupIDZ());
3503 }
3504
3505 bool IsWholeWaveFunc = Info->isWholeWaveFunction();
3506
3507 if (CallConv == CallingConv::AMDGPU_PS) {
3508 processPSInputArgs(Splits, CallConv, Ins, Skipped, FType, Info);
3509
3510 // At least one interpolation mode must be enabled or else the GPU will
3511 // hang.
3512 //
3513 // Check PSInputAddr instead of PSInputEnable. The idea is that if the user
3514 // set PSInputAddr, the user wants to enable some bits after the compilation
3515 // based on run-time states. Since we can't know what the final PSInputEna
3516 // will look like, so we shouldn't do anything here and the user should take
3517 // responsibility for the correct programming.
3518 //
3519 // Otherwise, the following restrictions apply:
3520 // - At least one of PERSP_* (0xF) or LINEAR_* (0x70) must be enabled.
3521 // - If POS_W_FLOAT (11) is enabled, at least one of PERSP_* must be
3522 // enabled too.
3523 if ((Info->getPSInputAddr() & 0x7F) == 0 ||
3524 ((Info->getPSInputAddr() & 0xF) == 0 && Info->isPSInputAllocated(11))) {
3525 CCInfo.AllocateReg(AMDGPU::VGPR0);
3526 CCInfo.AllocateReg(AMDGPU::VGPR1);
3527 Info->markPSInputAllocated(0);
3528 Info->markPSInputEnabled(0);
3529 }
3530 if (Subtarget->isAmdPalOS()) {
3531 // For isAmdPalOS, the user does not enable some bits after compilation
3532 // based on run-time states; the register values being generated here are
3533 // the final ones set in hardware. Therefore we need to apply the
3534 // workaround to PSInputAddr and PSInputEnable together. (The case where
3535 // a bit is set in PSInputAddr but not PSInputEnable is where the
3536 // frontend set up an input arg for a particular interpolation mode, but
3537 // nothing uses that input arg. Really we should have an earlier pass
3538 // that removes such an arg.)
3539 unsigned PsInputBits = Info->getPSInputAddr() & Info->getPSInputEnable();
3540 if ((PsInputBits & 0x7F) == 0 ||
3541 ((PsInputBits & 0xF) == 0 && (PsInputBits >> 11 & 1)))
3542 Info->markPSInputEnabled(llvm::countr_zero(Info->getPSInputAddr()));
3543 }
3544 } else if (IsKernel) {
3545 assert(Info->hasWorkGroupIDX() && Info->hasWorkItemIDX());
3546 } else {
3547 Splits.append(IsWholeWaveFunc ? std::next(Ins.begin()) : Ins.begin(),
3548 Ins.end());
3549 }
3550
3551 if (IsKernel)
3552 analyzeFormalArgumentsCompute(CCInfo, Ins);
3553
3554 if (IsEntryFunc) {
3555 allocateSpecialEntryInputVGPRs(CCInfo, MF, *TRI, *Info);
3556 allocateHSAUserSGPRs(CCInfo, MF, *TRI, *Info);
3557 if (IsKernel && Subtarget->hasKernargPreload())
3558 allocatePreloadKernArgSGPRs(CCInfo, ArgLocs, Ins, MF, *TRI, *Info);
3559
3560 allocateLDSKernelId(CCInfo, MF, *TRI, *Info);
3561 } else if (!IsGraphics) {
3562 // For the fixed ABI, pass workitem IDs in the last argument register.
3563 allocateSpecialInputVGPRsFixed(CCInfo, MF, *TRI, *Info);
3564
3565 // FIXME: Sink this into allocateSpecialInputSGPRs
3566 if (!Subtarget->hasFlatScratchEnabled())
3567 CCInfo.AllocateReg(Info->getScratchRSrcReg());
3568
3569 allocateSpecialInputSGPRs(CCInfo, MF, *TRI, *Info);
3570 }
3571
3572 if (!IsKernel) {
3573 CCAssignFn *AssignFn = CCAssignFnForCall(CallConv, isVarArg);
3574 CCInfo.AnalyzeFormalArguments(Splits, AssignFn);
3575
3576 // This assumes the registers are allocated by CCInfo in ascending order
3577 // with no gaps.
3578 Info->setNumWaveDispatchSGPRs(
3579 CCInfo.getFirstUnallocated(AMDGPU::SGPR_32RegClass.getRegisters()));
3580 Info->setNumWaveDispatchVGPRs(
3581 CCInfo.getFirstUnallocated(AMDGPU::VGPR_32RegClass.getRegisters()));
3582 } else if (Info->getNumKernargPreloadedSGPRs()) {
3583 Info->setNumWaveDispatchSGPRs(Info->getNumUserSGPRs());
3584 }
3585
3587
3588 if (IsWholeWaveFunc) {
3589 SDValue Setup = DAG.getNode(AMDGPUISD::WHOLE_WAVE_SETUP, DL,
3590 {MVT::i1, MVT::Other}, Chain);
3591 InVals.push_back(Setup.getValue(0));
3592 Chains.push_back(Setup.getValue(1));
3593 }
3594
3595 // FIXME: This is the minimum kernel argument alignment. We should improve
3596 // this to the maximum alignment of the arguments.
3597 //
3598 // FIXME: Alignment of explicit arguments totally broken with non-0 explicit
3599 // kern arg offset.
3600 const Align KernelArgBaseAlign = Align(16);
3601
3602 for (unsigned i = IsWholeWaveFunc ? 1 : 0, e = Ins.size(), ArgIdx = 0; i != e;
3603 ++i) {
3604 const ISD::InputArg &Arg = Ins[i];
3605 if ((Arg.isOrigArg() && Skipped[Arg.getOrigArgIndex()]) || IsError) {
3606 InVals.push_back(DAG.getPOISON(Arg.VT));
3607 continue;
3608 }
3609
3610 CCValAssign &VA = ArgLocs[ArgIdx++];
3611 MVT VT = VA.getLocVT();
3612
3613 if (IsEntryFunc && VA.isMemLoc()) {
3614 VT = Ins[i].VT;
3615 EVT MemVT = VA.getLocVT();
3616
3617 const uint64_t Offset = VA.getLocMemOffset();
3618 Align Alignment = commonAlignment(KernelArgBaseAlign, Offset);
3619
3620 if (Arg.Flags.isByRef()) {
3621 SDValue Ptr = lowerKernArgParameterPtr(DAG, DL, Chain, Offset);
3622
3623 const GCNTargetMachine &TM =
3624 static_cast<const GCNTargetMachine &>(getTargetMachine());
3625 if (!TM.isNoopAddrSpaceCast(AMDGPUAS::CONSTANT_ADDRESS,
3626 Arg.Flags.getPointerAddrSpace())) {
3629 }
3630
3631 InVals.push_back(Ptr);
3632 continue;
3633 }
3634
3635 SDValue NewArg;
3636 if (Arg.isOrigArg() && Info->getArgInfo().PreloadKernArgs.count(i)) {
3637 if (MemVT.getStoreSize() < 4 && Alignment < 4) {
3638 // In this case the argument is packed into the previous preload SGPR.
3639 int64_t AlignDownOffset = alignDown(Offset, 4);
3640 int64_t OffsetDiff = Offset - AlignDownOffset;
3641 EVT IntVT = MemVT.changeTypeToInteger();
3642
3643 const SIMachineFunctionInfo *Info =
3646 Register Reg =
3647 Info->getArgInfo().PreloadKernArgs.find(i)->getSecond().Regs[0];
3648
3649 assert(Reg);
3650 Register VReg = MRI.getLiveInVirtReg(Reg);
3651 SDValue Copy = DAG.getCopyFromReg(Chain, DL, VReg, MVT::i32);
3652
3653 SDValue ShiftAmt = DAG.getConstant(OffsetDiff * 8, DL, MVT::i32);
3654 SDValue Extract = DAG.getNode(ISD::SRL, DL, MVT::i32, Copy, ShiftAmt);
3655
3656 SDValue ArgVal = DAG.getNode(ISD::TRUNCATE, DL, IntVT, Extract);
3657 ArgVal = DAG.getNode(ISD::BITCAST, DL, MemVT, ArgVal);
3658 NewArg = convertArgType(DAG, VT, MemVT, DL, ArgVal,
3659 Ins[i].Flags.isSExt(), &Ins[i]);
3660
3661 NewArg = DAG.getMergeValues({NewArg, Copy.getValue(1)}, DL);
3662 } else {
3663 const SIMachineFunctionInfo *Info =
3666 const SmallVectorImpl<MCRegister> &PreloadRegs =
3667 Info->getArgInfo().PreloadKernArgs.find(i)->getSecond().Regs;
3668
3669 SDValue Copy;
3670 if (PreloadRegs.size() == 1) {
3671 Register VReg = MRI.getLiveInVirtReg(PreloadRegs[0]);
3672 const TargetRegisterClass *RC = MRI.getRegClass(VReg);
3673 NewArg = DAG.getCopyFromReg(
3674 Chain, DL, VReg,
3676 TRI->getRegSizeInBits(*RC)));
3677
3678 } else {
3679 // If the kernarg alignment does not match the alignment of the SGPR
3680 // tuple RC that can accommodate this argument, it will be built up
3681 // via copies from from the individual SGPRs that the argument was
3682 // preloaded to.
3684 for (auto Reg : PreloadRegs) {
3685 Register VReg = MRI.getLiveInVirtReg(Reg);
3686 Copy = DAG.getCopyFromReg(Chain, DL, VReg, MVT::i32);
3687 Elts.push_back(Copy);
3688 }
3689 NewArg =
3690 DAG.getBuildVector(EVT::getVectorVT(*DAG.getContext(), MVT::i32,
3691 PreloadRegs.size()),
3692 DL, Elts);
3693 }
3694
3695 // If the argument was preloaded to multiple consecutive 32-bit
3696 // registers because of misalignment between addressable SGPR tuples
3697 // and the argument size, we can still assume that because of kernarg
3698 // segment alignment restrictions that NewArg's size is the same as
3699 // MemVT and just do a bitcast. If MemVT is less than 32-bits we add a
3700 // truncate since we cannot preload to less than a single SGPR and the
3701 // MemVT may be smaller.
3702 EVT MemVTInt =
3704 if (MemVT.bitsLT(NewArg.getSimpleValueType()))
3705 NewArg = DAG.getNode(ISD::TRUNCATE, DL, MemVTInt, NewArg);
3706
3707 NewArg = DAG.getBitcast(MemVT, NewArg);
3708 NewArg = convertArgType(DAG, VT, MemVT, DL, NewArg,
3709 Ins[i].Flags.isSExt(), &Ins[i]);
3710 NewArg = DAG.getMergeValues({NewArg, Chain}, DL);
3711 }
3712 } else {
3713 // Hidden arguments that are in the kernel signature must be preloaded
3714 // to user SGPRs. Print a diagnostic error if a hidden argument is in
3715 // the argument list and is not preloaded.
3716 if (Arg.isOrigArg()) {
3717 Argument *OrigArg = Fn.getArg(Arg.getOrigArgIndex());
3718 if (OrigArg->hasAttribute("amdgpu-hidden-argument")) {
3720 *OrigArg->getParent(),
3721 "hidden argument in kernel signature was not preloaded",
3722 DL.getDebugLoc()));
3723 }
3724 }
3725
3726 NewArg =
3727 lowerKernargMemParameter(DAG, VT, MemVT, DL, Chain, Offset,
3728 Alignment, Ins[i].Flags.isSExt(), &Ins[i]);
3729 }
3730 Chains.push_back(NewArg.getValue(1));
3731
3732 auto *ParamTy =
3733 dyn_cast<PointerType>(FType->getParamType(Ins[i].getOrigArgIndex()));
3734 if (Subtarget->getGeneration() == AMDGPUSubtarget::SOUTHERN_ISLANDS &&
3735 ParamTy &&
3736 (ParamTy->getAddressSpace() == AMDGPUAS::LOCAL_ADDRESS ||
3737 ParamTy->getAddressSpace() == AMDGPUAS::REGION_ADDRESS)) {
3738 // On SI local pointers are just offsets into LDS, so they are always
3739 // less than 16-bits. On CI and newer they could potentially be
3740 // real pointers, so we can't guarantee their size.
3741 NewArg = DAG.getNode(ISD::AssertZext, DL, NewArg.getValueType(), NewArg,
3742 DAG.getValueType(MVT::i16));
3743 }
3744
3745 InVals.push_back(NewArg);
3746 continue;
3747 }
3748 if (!IsEntryFunc && VA.isMemLoc()) {
3749 SDValue Val = lowerStackParameter(DAG, VA, DL, Chain, Arg);
3750 InVals.push_back(Val);
3751 if (!Arg.Flags.isByVal())
3752 Chains.push_back(Val.getValue(1));
3753 continue;
3754 }
3755
3756 assert(VA.isRegLoc() && "Parameter must be in a register!");
3757
3758 Register Reg = VA.getLocReg();
3759 const TargetRegisterClass *RC = nullptr;
3760 if (AMDGPU::VGPR_32RegClass.contains(Reg))
3761 RC = &AMDGPU::VGPR_32RegClass;
3762 else if (AMDGPU::SGPR_32RegClass.contains(Reg))
3763 RC = &AMDGPU::SGPR_32RegClass;
3764 else
3765 llvm_unreachable("Unexpected register class in LowerFormalArguments!");
3766
3767 Reg = MF.addLiveIn(Reg, RC);
3768 SDValue Val = DAG.getCopyFromReg(Chain, DL, Reg, VT);
3769 if (Arg.Flags.isInReg() && RC == &AMDGPU::VGPR_32RegClass) {
3770 // FIXME: Need to forward the chains created by `CopyFromReg`s, make sure
3771 // they will read physical regs before any side effect instructions.
3772 SDValue ReadFirstLane =
3773 DAG.getTargetConstant(Intrinsic::amdgcn_readfirstlane, DL, MVT::i32);
3775 ReadFirstLane, Val);
3776 }
3777
3778 if (Arg.Flags.isSRet()) {
3779 // The return object should be reasonably addressable.
3780 Val = annotateStackObjectPointer(Val, DAG, DL,
3782 }
3783
3784 Val = convertABITypeToValueType(DAG, Val, VA, DL);
3785 InVals.push_back(Val);
3786 }
3787
3788 // Start adding system SGPRs.
3789 if (IsEntryFunc)
3790 allocateSystemSGPRs(CCInfo, MF, *Info, CallConv, IsGraphics);
3791
3792 unsigned StackArgSize = CCInfo.getStackSize();
3793 Info->setBytesInStackArgArea(StackArgSize);
3794
3795 return Chains.empty() ? Chain
3796 : DAG.getNode(ISD::TokenFactor, DL, MVT::Other, Chains);
3797}
3798
3799// TODO: If return values can't fit in registers, we should return as many as
3800// possible in registers before passing on stack.
3802 CallingConv::ID CallConv, MachineFunction &MF, bool IsVarArg,
3803 const SmallVectorImpl<ISD::OutputArg> &Outs, LLVMContext &Context,
3804 const Type *RetTy) const {
3805 // Replacing returns with sret/stack usage doesn't make sense for shaders.
3806 // FIXME: Also sort of a workaround for custom vector splitting in LowerReturn
3807 // for shaders. Vector types should be explicitly handled by CC.
3808 if (AMDGPU::isEntryFunctionCC(CallConv))
3809 return true;
3810
3812 CCState CCInfo(CallConv, IsVarArg, MF, RVLocs, Context);
3813 if (!CCInfo.CheckReturn(Outs, CCAssignFnForReturn(CallConv, IsVarArg)))
3814 return false;
3815
3816 // We must use the stack if return would require unavailable registers.
3817 unsigned MaxNumVGPRs = Subtarget->getMaxNumVGPRs(MF);
3818 unsigned TotalNumVGPRs = Subtarget->getAddressableNumArchVGPRs();
3819 for (unsigned i = MaxNumVGPRs; i < TotalNumVGPRs; ++i)
3820 if (CCInfo.isAllocated(AMDGPU::VGPR_32RegClass.getRegister(i)))
3821 return false;
3822
3823 return true;
3824}
3825
3826SDValue
3828 bool isVarArg,
3830 const SmallVectorImpl<SDValue> &OutVals,
3831 const SDLoc &DL, SelectionDAG &DAG) const {
3835
3836 if (AMDGPU::isKernel(CallConv)) {
3837 return AMDGPUTargetLowering::LowerReturn(Chain, CallConv, isVarArg, Outs,
3838 OutVals, DL, DAG);
3839 }
3840
3841 bool IsShader = AMDGPU::isShader(CallConv);
3842
3843 Info->setIfReturnsVoid(Outs.empty());
3844 bool IsWaveEnd = Info->returnsVoid() && IsShader;
3845
3846 // CCValAssign - represent the assignment of the return value to a location.
3848
3849 // CCState - Info about the registers and stack slots.
3850 CCState CCInfo(CallConv, isVarArg, DAG.getMachineFunction(), RVLocs,
3851 *DAG.getContext());
3852
3853 // Analyze outgoing return values.
3854 CCInfo.AnalyzeReturn(Outs, CCAssignFnForReturn(CallConv, isVarArg));
3855
3856 SDValue Glue;
3858 RetOps.push_back(Chain); // Operand #0 = Chain (updated below)
3859
3860 SDValue ReadFirstLane =
3861 DAG.getTargetConstant(Intrinsic::amdgcn_readfirstlane, DL, MVT::i32);
3862 // Copy the result values into the output registers.
3863 for (unsigned I = 0, RealRVLocIdx = 0, E = RVLocs.size(); I != E;
3864 ++I, ++RealRVLocIdx) {
3865 CCValAssign &VA = RVLocs[I];
3866 assert(VA.isRegLoc() && "Can only return in registers!");
3867 // TODO: Partially return in registers if return values don't fit.
3868 SDValue Arg = OutVals[RealRVLocIdx];
3869
3870 // Copied from other backends.
3871 switch (VA.getLocInfo()) {
3872 case CCValAssign::Full:
3873 break;
3874 case CCValAssign::BCvt:
3875 Arg = DAG.getNode(ISD::BITCAST, DL, VA.getLocVT(), Arg);
3876 break;
3877 case CCValAssign::SExt:
3878 Arg = DAG.getNode(ISD::SIGN_EXTEND, DL, VA.getLocVT(), Arg);
3879 break;
3880 case CCValAssign::ZExt:
3881 Arg = DAG.getNode(ISD::ZERO_EXTEND, DL, VA.getLocVT(), Arg);
3882 break;
3883 case CCValAssign::AExt:
3884 Arg = DAG.getNode(ISD::ANY_EXTEND, DL, VA.getLocVT(), Arg);
3885 break;
3886 default:
3887 llvm_unreachable("Unknown loc info!");
3888 }
3889 if (TRI->isSGPRPhysReg(VA.getLocReg()))
3891 ReadFirstLane, Arg);
3892 Chain = DAG.getCopyToReg(Chain, DL, VA.getLocReg(), Arg, Glue);
3893 Glue = Chain.getValue(1);
3894 RetOps.push_back(DAG.getRegister(VA.getLocReg(), VA.getLocVT()));
3895 }
3896
3897 // FIXME: Does sret work properly?
3898 if (!Info->isEntryFunction()) {
3899 const SIRegisterInfo *TRI = Subtarget->getRegisterInfo();
3900 const MCPhysReg *I =
3901 TRI->getCalleeSavedRegsViaCopy(&DAG.getMachineFunction());
3902 if (I) {
3903 for (; *I; ++I) {
3904 if (AMDGPU::SReg_64RegClass.contains(*I))
3905 RetOps.push_back(DAG.getRegister(*I, MVT::i64));
3906 else if (AMDGPU::SReg_32RegClass.contains(*I))
3907 RetOps.push_back(DAG.getRegister(*I, MVT::i32));
3908 else
3909 llvm_unreachable("Unexpected register class in CSRsViaCopy!");
3910 }
3911 }
3912 }
3913
3914 // Update chain and glue.
3915 RetOps[0] = Chain;
3916 if (Glue.getNode())
3917 RetOps.push_back(Glue);
3918
3919 unsigned Opc = AMDGPUISD::ENDPGM;
3920 if (!IsWaveEnd)
3921 Opc = Info->isWholeWaveFunction() ? AMDGPUISD::WHOLE_WAVE_RETURN
3922 : IsShader ? AMDGPUISD::RETURN_TO_EPILOG
3923 : AMDGPUISD::RET_GLUE;
3924 return DAG.getNode(Opc, DL, MVT::Other, RetOps);
3925}
3926
3928 SDValue Chain, SDValue InGlue, CallingConv::ID CallConv, bool IsVarArg,
3929 const SmallVectorImpl<ISD::InputArg> &Ins, const SDLoc &DL,
3930 SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals, bool IsThisReturn,
3931 SDValue ThisVal) const {
3932 CCAssignFn *RetCC = CCAssignFnForReturn(CallConv, IsVarArg);
3933
3934 // Assign locations to each value returned by this call.
3936 CCState CCInfo(CallConv, IsVarArg, DAG.getMachineFunction(), RVLocs,
3937 *DAG.getContext());
3938 CCInfo.AnalyzeCallResult(Ins, RetCC);
3939
3940 // Copy all of the result registers out of their specified physreg.
3941 for (CCValAssign VA : RVLocs) {
3942 SDValue Val;
3943
3944 if (VA.isRegLoc()) {
3945 Val =
3946 DAG.getCopyFromReg(Chain, DL, VA.getLocReg(), VA.getLocVT(), InGlue);
3947 Chain = Val.getValue(1);
3948 InGlue = Val.getValue(2);
3949 } else if (VA.isMemLoc()) {
3950 report_fatal_error("TODO: return values in memory");
3951 } else
3952 llvm_unreachable("unknown argument location type");
3953
3954 switch (VA.getLocInfo()) {
3955 case CCValAssign::Full:
3956 break;
3957 case CCValAssign::BCvt:
3958 Val = DAG.getNode(ISD::BITCAST, DL, VA.getValVT(), Val);
3959 break;
3960 case CCValAssign::ZExt:
3961 Val = DAG.getNode(ISD::AssertZext, DL, VA.getLocVT(), Val,
3962 DAG.getValueType(VA.getValVT()));
3963 Val = DAG.getNode(ISD::TRUNCATE, DL, VA.getValVT(), Val);
3964 break;
3965 case CCValAssign::SExt:
3966 Val = DAG.getNode(ISD::AssertSext, DL, VA.getLocVT(), Val,
3967 DAG.getValueType(VA.getValVT()));
3968 Val = DAG.getNode(ISD::TRUNCATE, DL, VA.getValVT(), Val);
3969 break;
3970 case CCValAssign::AExt:
3971 Val = DAG.getNode(ISD::TRUNCATE, DL, VA.getValVT(), Val);
3972 break;
3973 default:
3974 llvm_unreachable("Unknown loc info!");
3975 }
3976
3977 InVals.push_back(Val);
3978 }
3979
3980 return Chain;
3981}
3982
3983// Add code to pass special inputs required depending on used features separate
3984// from the explicit user arguments present in the IR.
3986 CallLoweringInfo &CLI, CCState &CCInfo, const SIMachineFunctionInfo &Info,
3987 SmallVectorImpl<std::pair<unsigned, SDValue>> &RegsToPass,
3988 SmallVectorImpl<SDValue> &MemOpChains, SDValue Chain) const {
3989 // If we don't have a call site, this was a call inserted by
3990 // legalization. These can never use special inputs.
3991 if (!CLI.CB)
3992 return;
3993
3994 SelectionDAG &DAG = CLI.DAG;
3995 const SDLoc &DL = CLI.DL;
3996 const Function &F = DAG.getMachineFunction().getFunction();
3997
3998 const SIRegisterInfo *TRI = Subtarget->getRegisterInfo();
3999 const AMDGPUFunctionArgInfo &CallerArgInfo = Info.getArgInfo();
4000
4001 const AMDGPUFunctionArgInfo &CalleeArgInfo =
4003
4004 // TODO: Unify with private memory register handling. This is complicated by
4005 // the fact that at least in kernels, the input argument is not necessarily
4006 // in the same location as the input.
4007 // clang-format off
4008 static constexpr std::pair<AMDGPUFunctionArgInfo::PreloadedValue,
4009 std::array<StringLiteral, 2>> ImplicitAttrs[] = {
4010 {AMDGPUFunctionArgInfo::DISPATCH_PTR, {"amdgpu-no-dispatch-ptr", ""}},
4011 {AMDGPUFunctionArgInfo::QUEUE_PTR, {"amdgpu-no-queue-ptr", ""}},
4012 {AMDGPUFunctionArgInfo::IMPLICIT_ARG_PTR, {"amdgpu-no-implicitarg-ptr", ""}},
4013 {AMDGPUFunctionArgInfo::DISPATCH_ID, {"amdgpu-no-dispatch-id", ""}},
4014 {AMDGPUFunctionArgInfo::WORKGROUP_ID_X, {"amdgpu-no-workgroup-id-x", "amdgpu-no-cluster-id-x"}},
4015 {AMDGPUFunctionArgInfo::WORKGROUP_ID_Y, {"amdgpu-no-workgroup-id-y", "amdgpu-no-cluster-id-y"}},
4016 {AMDGPUFunctionArgInfo::WORKGROUP_ID_Z, {"amdgpu-no-workgroup-id-z", "amdgpu-no-cluster-id-z"}},
4017 {AMDGPUFunctionArgInfo::LDS_KERNEL_ID, {"amdgpu-no-lds-kernel-id", ""}},
4018 };
4019 // clang-format on
4020
4021 for (auto [InputID, Attrs] : ImplicitAttrs) {
4022 // If the callee does not use the attribute value, skip copying the value.
4023 if (all_of(Attrs, [&](StringRef Attr) {
4024 return Attr.empty() || CLI.CB->hasFnAttr(Attr);
4025 }))
4026 continue;
4027
4028 const auto [OutgoingArg, ArgRC, ArgTy] =
4029 CalleeArgInfo.getPreloadedValue(InputID);
4030 if (!OutgoingArg)
4031 continue;
4032
4033 const auto [IncomingArg, IncomingArgRC, Ty] =
4034 CallerArgInfo.getPreloadedValue(InputID);
4035 assert(IncomingArgRC == ArgRC);
4036
4037 // All special arguments are ints for now.
4038 EVT ArgVT = TRI->getSpillSize(*ArgRC) == 8 ? MVT::i64 : MVT::i32;
4039 SDValue InputReg;
4040
4041 if (IncomingArg) {
4042 InputReg = loadInputValue(DAG, ArgRC, ArgVT, DL, *IncomingArg);
4043 } else if (InputID == AMDGPUFunctionArgInfo::IMPLICIT_ARG_PTR) {
4044 // The implicit arg ptr is special because it doesn't have a corresponding
4045 // input for kernels, and is computed from the kernarg segment pointer.
4046 InputReg = getImplicitArgPtr(DAG, DL);
4047 } else if (InputID == AMDGPUFunctionArgInfo::LDS_KERNEL_ID) {
4048 std::optional<uint32_t> Id =
4050 if (Id.has_value()) {
4051 InputReg = DAG.getConstant(*Id, DL, ArgVT);
4052 } else {
4053 InputReg = DAG.getPOISON(ArgVT);
4054 }
4055 } else {
4056 // We may have proven the input wasn't needed, although the ABI is
4057 // requiring it. We just need to allocate the register appropriately.
4058 InputReg = DAG.getPOISON(ArgVT);
4059 }
4060
4061 if (OutgoingArg->isRegister()) {
4062 RegsToPass.emplace_back(OutgoingArg->getRegister(), InputReg);
4063 if (!CCInfo.AllocateReg(OutgoingArg->getRegister()))
4064 report_fatal_error("failed to allocate implicit input argument");
4065 } else {
4066 unsigned SpecialArgOffset =
4067 CCInfo.AllocateStack(ArgVT.getStoreSize(), Align(4));
4068 SDValue ArgStore =
4069 storeStackInputValue(DAG, DL, Chain, InputReg, SpecialArgOffset);
4070 MemOpChains.push_back(ArgStore);
4071 }
4072 }
4073
4074 // Pack workitem IDs into a single register or pass it as is if already
4075 // packed.
4076
4077 auto [OutgoingArg, ArgRC, Ty] =
4079 if (!OutgoingArg)
4080 std::tie(OutgoingArg, ArgRC, Ty) =
4082 if (!OutgoingArg)
4083 std::tie(OutgoingArg, ArgRC, Ty) =
4085 if (!OutgoingArg)
4086 return;
4087
4088 const ArgDescriptor *IncomingArgX = std::get<0>(
4090 const ArgDescriptor *IncomingArgY = std::get<0>(
4092 const ArgDescriptor *IncomingArgZ = std::get<0>(
4094
4095 SDValue InputReg;
4096 SDLoc SL;
4097
4098 const bool NeedWorkItemIDX = !CLI.CB->hasFnAttr("amdgpu-no-workitem-id-x");
4099 const bool NeedWorkItemIDY = !CLI.CB->hasFnAttr("amdgpu-no-workitem-id-y");
4100 const bool NeedWorkItemIDZ = !CLI.CB->hasFnAttr("amdgpu-no-workitem-id-z");
4101
4102 // If incoming ids are not packed we need to pack them.
4103 if (IncomingArgX && !IncomingArgX->isMasked() && CalleeArgInfo.WorkItemIDX &&
4104 NeedWorkItemIDX) {
4105 if (Subtarget->getMaxWorkitemID(F, 0) != 0) {
4106 InputReg = loadInputValue(DAG, ArgRC, MVT::i32, DL, *IncomingArgX);
4107 } else {
4108 InputReg = DAG.getConstant(0, DL, MVT::i32);
4109 }
4110 }
4111
4112 if (IncomingArgY && !IncomingArgY->isMasked() && CalleeArgInfo.WorkItemIDY &&
4113 NeedWorkItemIDY && Subtarget->getMaxWorkitemID(F, 1) != 0) {
4114 SDValue Y = loadInputValue(DAG, ArgRC, MVT::i32, DL, *IncomingArgY);
4115 Y = DAG.getNode(ISD::SHL, SL, MVT::i32, Y,
4116 DAG.getShiftAmountConstant(10, MVT::i32, SL));
4117 InputReg = InputReg.getNode()
4118 ? DAG.getNode(ISD::OR, SL, MVT::i32, InputReg, Y)
4119 : Y;
4120 }
4121
4122 if (IncomingArgZ && !IncomingArgZ->isMasked() && CalleeArgInfo.WorkItemIDZ &&
4123 NeedWorkItemIDZ && Subtarget->getMaxWorkitemID(F, 2) != 0) {
4124 SDValue Z = loadInputValue(DAG, ArgRC, MVT::i32, DL, *IncomingArgZ);
4125 Z = DAG.getNode(ISD::SHL, SL, MVT::i32, Z,
4126 DAG.getShiftAmountConstant(20, MVT::i32, SL));
4127 InputReg = InputReg.getNode()
4128 ? DAG.getNode(ISD::OR, SL, MVT::i32, InputReg, Z)
4129 : Z;
4130 }
4131
4132 if (!InputReg && (NeedWorkItemIDX || NeedWorkItemIDY || NeedWorkItemIDZ)) {
4133 if (!IncomingArgX && !IncomingArgY && !IncomingArgZ) {
4134 // We're in a situation where the outgoing function requires the workitem
4135 // ID, but the calling function does not have it (e.g a graphics function
4136 // calling a C calling convention function). This is illegal, but we need
4137 // to produce something.
4138 InputReg = DAG.getPOISON(MVT::i32);
4139 } else {
4140 // Workitem ids are already packed, any of present incoming arguments
4141 // will carry all required fields.
4142 ArgDescriptor IncomingArg =
4143 ArgDescriptor::createArg(IncomingArgX ? *IncomingArgX
4144 : IncomingArgY ? *IncomingArgY
4145 : *IncomingArgZ,
4146 ~0u);
4147 InputReg = loadInputValue(DAG, ArgRC, MVT::i32, DL, IncomingArg);
4148 }
4149 }
4150
4151 if (OutgoingArg->isRegister()) {
4152 if (InputReg)
4153 RegsToPass.emplace_back(OutgoingArg->getRegister(), InputReg);
4154
4155 CCInfo.AllocateReg(OutgoingArg->getRegister());
4156 } else {
4157 unsigned SpecialArgOffset = CCInfo.AllocateStack(4, Align(4));
4158 if (InputReg) {
4159 SDValue ArgStore =
4160 storeStackInputValue(DAG, DL, Chain, InputReg, SpecialArgOffset);
4161 MemOpChains.push_back(ArgStore);
4162 }
4163 }
4164}
4165
4167 SDValue Callee, CallingConv::ID CalleeCC, bool IsVarArg,
4169 const SmallVectorImpl<SDValue> &OutVals,
4170 const SmallVectorImpl<ISD::InputArg> &Ins, SelectionDAG &DAG) const {
4171 if (AMDGPU::isChainCC(CalleeCC))
4172 return true;
4173
4174 if (!AMDGPU::mayTailCallThisCC(CalleeCC))
4175 return false;
4176
4177 // For a divergent call target, we need to do a waterfall loop over the
4178 // possible callees which precludes us from using a simple jump.
4179 if (Callee->isDivergent())
4180 return false;
4181
4183 const Function &CallerF = MF.getFunction();
4184 CallingConv::ID CallerCC = CallerF.getCallingConv();
4186 const uint32_t *CallerPreserved = TRI->getCallPreservedMask(MF, CallerCC);
4187
4188 // Kernels aren't callable, and don't have a live in return address so it
4189 // doesn't make sense to do a tail call with entry functions.
4190 if (!CallerPreserved)
4191 return false;
4192
4193 bool CCMatch = CallerCC == CalleeCC;
4194
4196 if (AMDGPU::canGuaranteeTCO(CalleeCC) && CCMatch)
4197 return true;
4198 return false;
4199 }
4200
4201 // TODO: Can we handle var args?
4202 if (IsVarArg)
4203 return false;
4204
4205 for (const Argument &Arg : CallerF.args()) {
4206 if (Arg.hasByValAttr())
4207 return false;
4208 }
4209
4210 LLVMContext &Ctx = *DAG.getContext();
4211
4212 // Check that the call results are passed in the same way.
4213 if (!CCState::resultsCompatible(CalleeCC, CallerCC, MF, Ctx, Ins,
4214 CCAssignFnForCall(CalleeCC, IsVarArg),
4215 CCAssignFnForCall(CallerCC, IsVarArg)))
4216 return false;
4217
4218 // The callee has to preserve all registers the caller needs to preserve.
4219 if (!CCMatch) {
4220 const uint32_t *CalleePreserved = TRI->getCallPreservedMask(MF, CalleeCC);
4221 if (!TRI->regmaskSubsetEqual(CallerPreserved, CalleePreserved))
4222 return false;
4223 }
4224
4225 // Nothing more to check if the callee is taking no arguments.
4226 if (Outs.empty())
4227 return true;
4228
4230 CCState CCInfo(CalleeCC, IsVarArg, MF, ArgLocs, Ctx);
4231
4232 // FIXME: We are not allocating special input registers, so we will be
4233 // deciding based on incorrect register assignments.
4234 CCInfo.AnalyzeCallOperands(Outs, CCAssignFnForCall(CalleeCC, IsVarArg));
4235
4236 const SIMachineFunctionInfo *FuncInfo = MF.getInfo<SIMachineFunctionInfo>();
4237 // If the stack arguments for this call do not fit into our own save area then
4238 // the call cannot be made tail.
4239 // TODO: Is this really necessary?
4240 if (CCInfo.getStackSize() > FuncInfo->getBytesInStackArgArea())
4241 return false;
4242
4243 for (const auto &[CCVA, ArgVal] : zip_equal(ArgLocs, OutVals)) {
4244 // FIXME: What about inreg arguments that end up passed in memory?
4245 if (!CCVA.isRegLoc())
4246 continue;
4247
4248 // If we are passing an argument in an SGPR, and the value is divergent,
4249 // this call requires a waterfall loop.
4250 if (ArgVal->isDivergent() && TRI->isSGPRPhysReg(CCVA.getLocReg())) {
4251 LLVM_DEBUG(
4252 dbgs() << "Cannot tail call due to divergent outgoing argument in "
4253 << printReg(CCVA.getLocReg(), TRI) << '\n');
4254 return false;
4255 }
4256 }
4257
4258 const MachineRegisterInfo &MRI = MF.getRegInfo();
4259 return parametersInCSRMatch(MRI, CallerPreserved, ArgLocs, OutVals);
4260}
4261
4263 if (!CI->isTailCall())
4264 return false;
4265
4266 const Function *ParentFn = CI->getFunction();
4268 return false;
4269 return true;
4270}
4271
4272namespace {
4273// Chain calls have special arguments that we need to handle. These are
4274// tagging along at the end of the arguments list(s), after the SGPR and VGPR
4275// arguments (index 0 and 1 respectively).
4276enum ChainCallArgIdx {
4277 Exec = 2,
4278 Flags,
4279 NumVGPRs,
4280 FallbackExec,
4281 FallbackCallee
4282};
4283} // anonymous namespace
4284
4285// The wave scratch offset register is used as the global base pointer.
4287 SmallVectorImpl<SDValue> &InVals) const {
4288 CallingConv::ID CallConv = CLI.CallConv;
4289 bool IsChainCallConv = AMDGPU::isChainCC(CallConv);
4290
4291 SelectionDAG &DAG = CLI.DAG;
4292
4293 const SDLoc &DL = CLI.DL;
4294 SDValue Chain = CLI.Chain;
4295 SDValue Callee = CLI.Callee;
4296
4297 llvm::SmallVector<SDValue, 6> ChainCallSpecialArgs;
4298 bool UsesDynamicVGPRs = false;
4299 if (IsChainCallConv) {
4300 // The last arguments should be the value that we need to put in EXEC,
4301 // followed by the flags and any other arguments with special meanings.
4302 // Pop them out of CLI.Outs and CLI.OutVals before we do any processing so
4303 // we don't treat them like the "real" arguments.
4304 auto RequestedExecIt =
4305 llvm::find_if(CLI.Outs, [](const ISD::OutputArg &Arg) {
4306 return Arg.OrigArgIndex == 2;
4307 });
4308 assert(RequestedExecIt != CLI.Outs.end() && "No node for EXEC");
4309
4310 size_t SpecialArgsBeginIdx = RequestedExecIt - CLI.Outs.begin();
4311 CLI.OutVals.erase(CLI.OutVals.begin() + SpecialArgsBeginIdx,
4312 CLI.OutVals.end());
4313 CLI.Outs.erase(RequestedExecIt, CLI.Outs.end());
4314
4315 assert(CLI.Outs.back().OrigArgIndex < 2 &&
4316 "Haven't popped all the special args");
4317
4318 TargetLowering::ArgListEntry RequestedExecArg =
4319 CLI.Args[ChainCallArgIdx::Exec];
4320 if (!RequestedExecArg.Ty->isIntegerTy(Subtarget->getWavefrontSize()))
4321 return lowerUnhandledCall(CLI, InVals, "Invalid value for EXEC");
4322
4323 // Convert constants into TargetConstants, so they become immediate operands
4324 // instead of being selected into S_MOV.
4325 auto PushNodeOrTargetConstant = [&](TargetLowering::ArgListEntry Arg) {
4326 if (const auto *ArgNode = dyn_cast<ConstantSDNode>(Arg.Node)) {
4327 ChainCallSpecialArgs.push_back(DAG.getTargetConstant(
4328 ArgNode->getAPIntValue(), DL, ArgNode->getValueType(0)));
4329 } else
4330 ChainCallSpecialArgs.push_back(Arg.Node);
4331 };
4332
4333 PushNodeOrTargetConstant(RequestedExecArg);
4334
4335 // Process any other special arguments depending on the value of the flags.
4336 TargetLowering::ArgListEntry Flags = CLI.Args[ChainCallArgIdx::Flags];
4337
4338 const APInt &FlagsValue = cast<ConstantSDNode>(Flags.Node)->getAPIntValue();
4339 if (FlagsValue.isZero()) {
4340 if (CLI.Args.size() > ChainCallArgIdx::Flags + 1)
4341 return lowerUnhandledCall(CLI, InVals,
4342 "no additional args allowed if flags == 0");
4343 } else if (FlagsValue.isOneBitSet(0)) {
4344 if (CLI.Args.size() != ChainCallArgIdx::FallbackCallee + 1) {
4345 return lowerUnhandledCall(CLI, InVals, "expected 3 additional args");
4346 }
4347
4348 if (!Subtarget->isWave32()) {
4349 return lowerUnhandledCall(
4350 CLI, InVals, "dynamic VGPR mode is only supported for wave32");
4351 }
4352
4353 UsesDynamicVGPRs = true;
4354 std::for_each(CLI.Args.begin() + ChainCallArgIdx::NumVGPRs,
4355 CLI.Args.end(), PushNodeOrTargetConstant);
4356 }
4357 }
4358
4360 SmallVector<SDValue, 32> &OutVals = CLI.OutVals;
4362 bool &IsTailCall = CLI.IsTailCall;
4363 bool IsVarArg = CLI.IsVarArg;
4364 bool IsSibCall = false;
4366
4367 if (Callee.isUndef() || isNullConstant(Callee)) {
4368 if (!CLI.IsTailCall) {
4369 for (ISD::InputArg &Arg : CLI.Ins)
4370 InVals.push_back(DAG.getPOISON(Arg.VT));
4371 }
4372
4373 return Chain;
4374 }
4375
4376 if (IsVarArg) {
4377 return lowerUnhandledCall(CLI, InVals,
4378 "unsupported call to variadic function ");
4379 }
4380
4381 if (!CLI.CB)
4382 return lowerUnhandledCall(CLI, InVals, "unsupported libcall legalization");
4383
4384 if (IsTailCall && MF.getTarget().Options.GuaranteedTailCallOpt) {
4385 return lowerUnhandledCall(CLI, InVals,
4386 "unsupported required tail call to function ");
4387 }
4388
4389 if (IsTailCall) {
4390 IsTailCall = isEligibleForTailCallOptimization(Callee, CallConv, IsVarArg,
4391 Outs, OutVals, Ins, DAG);
4392 if (!IsTailCall &&
4393 ((CLI.CB && CLI.CB->isMustTailCall()) || IsChainCallConv)) {
4394 report_fatal_error("failed to perform tail call elimination on a call "
4395 "site marked musttail or on llvm.amdgcn.cs.chain");
4396 }
4397
4398 bool TailCallOpt = MF.getTarget().Options.GuaranteedTailCallOpt;
4399
4400 // A sibling call is one where we're under the usual C ABI and not planning
4401 // to change that but can still do a tail call:
4402 if (!TailCallOpt && IsTailCall)
4403 IsSibCall = true;
4404
4405 if (IsTailCall)
4406 ++NumTailCalls;
4407 }
4408
4411 SmallVector<SDValue, 8> MemOpChains;
4412
4413 // Analyze operands of the call, assigning locations to each operand.
4415 CCState CCInfo(CallConv, IsVarArg, MF, ArgLocs, *DAG.getContext());
4416 CCAssignFn *AssignFn = CCAssignFnForCall(CallConv, IsVarArg);
4417
4418 if (CallConv != CallingConv::AMDGPU_Gfx && !AMDGPU::isChainCC(CallConv) &&
4420 // With a fixed ABI, allocate fixed registers before user arguments.
4421 passSpecialInputs(CLI, CCInfo, *Info, RegsToPass, MemOpChains, Chain);
4422 }
4423
4424 // Mark the scratch resource descriptor as allocated so the CC analysis
4425 // does not assign user arguments to these registers, matching the callee.
4426 if (!Subtarget->hasFlatScratchEnabled())
4427 CCInfo.AllocateReg(Info->getScratchRSrcReg());
4428
4429 CCInfo.AnalyzeCallOperands(Outs, AssignFn);
4430
4431 // Get a count of how many bytes are to be pushed on the stack.
4432 unsigned NumBytes = CCInfo.getStackSize();
4433
4434 if (IsSibCall) {
4435 // Since we're not changing the ABI to make this a tail call, the memory
4436 // operands are already available in the caller's incoming argument space.
4437 NumBytes = 0;
4438 }
4439
4440 // FPDiff is the byte offset of the call's argument area from the callee's.
4441 // Stores to callee stack arguments will be placed in FixedStackSlots offset
4442 // by this amount for a tail call. In a sibling call it must be 0 because the
4443 // caller will deallocate the entire stack and the callee still expects its
4444 // arguments to begin at SP+0. Completely unused for non-tail calls.
4445 int32_t FPDiff = 0;
4446 MachineFrameInfo &MFI = MF.getFrameInfo();
4447 auto *TRI = Subtarget->getRegisterInfo();
4448
4449 // Adjust the stack pointer for the new arguments...
4450 // These operations are automatically eliminated by the prolog/epilog pass
4451 if (!IsSibCall)
4452 Chain = DAG.getCALLSEQ_START(Chain, 0, 0, DL);
4453
4454 if (!IsSibCall || IsChainCallConv) {
4455 if (!Subtarget->hasFlatScratchEnabled()) {
4456 SmallVector<SDValue, 4> CopyFromChains;
4457
4458 // In the HSA case, this should be an identity copy.
4459 SDValue ScratchRSrcReg =
4460 DAG.getCopyFromReg(Chain, DL, Info->getScratchRSrcReg(), MVT::v4i32);
4461 RegsToPass.emplace_back(IsChainCallConv
4462 ? AMDGPU::SGPR48_SGPR49_SGPR50_SGPR51
4463 : AMDGPU::SGPR0_SGPR1_SGPR2_SGPR3,
4464 ScratchRSrcReg);
4465 CopyFromChains.push_back(ScratchRSrcReg.getValue(1));
4466 Chain = DAG.getTokenFactor(DL, CopyFromChains);
4467 }
4468 }
4469
4470 const unsigned NumSpecialInputs = RegsToPass.size();
4471
4472 MVT PtrVT = MVT::i32;
4473
4474 // Walk the register/memloc assignments, inserting copies/loads.
4475 for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) {
4476 CCValAssign &VA = ArgLocs[i];
4477 SDValue Arg = OutVals[i];
4478
4479 // Promote the value if needed.
4480 switch (VA.getLocInfo()) {
4481 case CCValAssign::Full:
4482 break;
4483 case CCValAssign::BCvt:
4484 Arg = DAG.getNode(ISD::BITCAST, DL, VA.getLocVT(), Arg);
4485 break;
4486 case CCValAssign::ZExt:
4487 Arg = DAG.getNode(ISD::ZERO_EXTEND, DL, VA.getLocVT(), Arg);
4488 break;
4489 case CCValAssign::SExt:
4490 Arg = DAG.getNode(ISD::SIGN_EXTEND, DL, VA.getLocVT(), Arg);
4491 break;
4492 case CCValAssign::AExt:
4493 Arg = DAG.getNode(ISD::ANY_EXTEND, DL, VA.getLocVT(), Arg);
4494 break;
4495 case CCValAssign::FPExt:
4496 Arg = DAG.getNode(ISD::FP_EXTEND, DL, VA.getLocVT(), Arg);
4497 break;
4498 default:
4499 llvm_unreachable("Unknown loc info!");
4500 }
4501
4502 if (VA.isRegLoc()) {
4503 RegsToPass.push_back(std::pair(VA.getLocReg(), Arg));
4504 } else {
4505 assert(VA.isMemLoc());
4506
4507 SDValue DstAddr;
4508 MachinePointerInfo DstInfo;
4509
4510 unsigned LocMemOffset = VA.getLocMemOffset();
4511 int32_t Offset = LocMemOffset;
4512
4513 SDValue PtrOff = DAG.getConstant(Offset, DL, PtrVT);
4514 MaybeAlign Alignment;
4515
4516 if (IsTailCall) {
4517 ISD::ArgFlagsTy Flags = Outs[i].Flags;
4518 unsigned OpSize = Flags.isByVal() ? Flags.getByValSize()
4519 : VA.getValVT().getStoreSize();
4520
4521 // FIXME: We can have better than the minimum byval required alignment.
4522 Alignment =
4523 Flags.isByVal()
4524 ? Flags.getNonZeroByValAlign()
4525 : commonAlignment(Subtarget->getStackAlignment(), Offset);
4526
4527 Offset = Offset + FPDiff;
4528 int FI = MFI.CreateFixedObject(OpSize, Offset, true);
4529
4530 DstAddr = DAG.getFrameIndex(FI, PtrVT);
4531 DstInfo = MachinePointerInfo::getFixedStack(MF, FI);
4532
4533 // Make sure any stack arguments overlapping with where we're storing
4534 // are loaded before this eventual operation. Otherwise they'll be
4535 // clobbered.
4536
4537 // FIXME: Why is this really necessary? This seems to just result in a
4538 // lot of code to copy the stack and write them back to the same
4539 // locations, which are supposed to be immutable?
4540 Chain = addTokenForArgument(Chain, DAG, MFI, FI);
4541 } else {
4542 // Stores to the argument stack area are relative to the stack pointer.
4543 SDValue SP = DAG.getCopyFromReg(Chain, DL, Info->getStackPtrOffsetReg(),
4544 MVT::i32);
4545 DstAddr = DAG.getNode(ISD::ADD, DL, MVT::i32, SP, PtrOff);
4546 DstInfo = MachinePointerInfo::getStack(MF, LocMemOffset);
4547 Alignment =
4548 commonAlignment(Subtarget->getStackAlignment(), LocMemOffset);
4549 }
4550
4551 if (Outs[i].Flags.isByVal()) {
4552 SDValue SizeNode =
4553 DAG.getConstant(Outs[i].Flags.getByValSize(), DL, MVT::i32);
4554 SDValue Cpy =
4555 DAG.getMemcpy(Chain, DL, DstAddr, Arg, SizeNode,
4556 Outs[i].Flags.getNonZeroByValAlign(),
4557 Outs[i].Flags.getNonZeroByValAlign(),
4558 /*isVol = */ false, /*AlwaysInline = */ true,
4559 /*CI=*/nullptr, std::nullopt, DstInfo,
4561
4562 MemOpChains.push_back(Cpy);
4563 } else {
4564 SDValue Store =
4565 DAG.getStore(Chain, DL, Arg, DstAddr, DstInfo, Alignment);
4566 MemOpChains.push_back(Store);
4567 }
4568 }
4569 }
4570
4571 if (!MemOpChains.empty())
4572 Chain = DAG.getNode(ISD::TokenFactor, DL, MVT::Other, MemOpChains);
4573
4574 SDValue ReadFirstLaneID =
4575 DAG.getTargetConstant(Intrinsic::amdgcn_readfirstlane, DL, MVT::i32);
4576
4577 SDValue TokenGlue;
4578 if (CLI.ConvergenceControlToken) {
4579 TokenGlue = DAG.getNode(ISD::CONVERGENCECTRL_GLUE, DL, MVT::Glue,
4581 }
4582
4583 // Build a sequence of copy-to-reg nodes chained together with token chain
4584 // and flag operands which copy the outgoing args into the appropriate regs.
4585 SDValue InGlue;
4586
4587 unsigned ArgIdx = 0;
4588 for (auto [Reg, Val] : RegsToPass) {
4589 if (ArgIdx++ >= NumSpecialInputs &&
4590 (IsChainCallConv || !Val->isDivergent()) && TRI->isSGPRPhysReg(Reg)) {
4591 // For chain calls, the inreg arguments are required to be
4592 // uniform. Speculatively Insert a readfirstlane in case we cannot prove
4593 // they are uniform.
4594 //
4595 // For other calls, if an inreg arguments is known to be uniform,
4596 // speculatively insert a readfirstlane in case it is in a VGPR.
4597 //
4598 // FIXME: We need to execute this in a waterfall loop if it is a divergent
4599 // value, so let that continue to produce invalid code.
4600
4601 SmallVector<SDValue, 3> ReadfirstlaneArgs({ReadFirstLaneID, Val});
4602 if (TokenGlue)
4603 ReadfirstlaneArgs.push_back(TokenGlue);
4605 ReadfirstlaneArgs);
4606 }
4607
4608 Chain = DAG.getCopyToReg(Chain, DL, Reg, Val, InGlue);
4609 InGlue = Chain.getValue(1);
4610 }
4611
4612 // We don't usually want to end the call-sequence here because we would tidy
4613 // the frame up *after* the call, however in the ABI-changing tail-call case
4614 // we've carefully laid out the parameters so that when sp is reset they'll be
4615 // in the correct location.
4616 if (IsTailCall && !IsSibCall) {
4617 Chain = DAG.getCALLSEQ_END(Chain, NumBytes, 0, InGlue, DL);
4618 InGlue = Chain.getValue(1);
4619 }
4620
4621 std::vector<SDValue> Ops({Chain});
4622
4623 // Add a redundant copy of the callee global which will not be legalized, as
4624 // we need direct access to the callee later.
4626 const GlobalValue *GV = GSD->getGlobal();
4627 Ops.push_back(Callee);
4628 Ops.push_back(DAG.getTargetGlobalAddress(GV, DL, MVT::i64));
4629 } else {
4630 if (IsTailCall) {
4631 // isEligibleForTailCallOptimization considered whether the call target is
4632 // divergent, but we may still end up with a uniform value in a VGPR.
4633 // Insert a readfirstlane just in case.
4634 SDValue ReadFirstLaneID =
4635 DAG.getTargetConstant(Intrinsic::amdgcn_readfirstlane, DL, MVT::i32);
4636
4637 SmallVector<SDValue, 3> ReadfirstlaneArgs({ReadFirstLaneID, Callee});
4638 if (TokenGlue)
4639 ReadfirstlaneArgs.push_back(TokenGlue); // Wire up convergence token.
4640 Callee = DAG.getNode(ISD::INTRINSIC_WO_CHAIN, DL, Callee.getValueType(),
4641 ReadfirstlaneArgs);
4642 }
4643
4644 Ops.push_back(Callee);
4645 Ops.push_back(DAG.getTargetConstant(0, DL, MVT::i64));
4646 }
4647
4648 if (IsTailCall) {
4649 // Each tail call may have to adjust the stack by a different amount, so
4650 // this information must travel along with the operation for eventual
4651 // consumption by emitEpilogue.
4652 Ops.push_back(DAG.getTargetConstant(FPDiff, DL, MVT::i32));
4653 }
4654
4655 if (IsChainCallConv)
4656 llvm::append_range(Ops, ChainCallSpecialArgs);
4657
4658 // Add argument registers to the end of the list so that they are known live
4659 // into the call.
4660 for (auto &[Reg, Val] : RegsToPass)
4661 Ops.push_back(DAG.getRegister(Reg, Val.getValueType()));
4662
4663 // Add a register mask operand representing the call-preserved registers.
4664 const uint32_t *Mask = TRI->getCallPreservedMask(MF, CallConv);
4665 assert(Mask && "Missing call preserved mask for calling convention");
4666 Ops.push_back(DAG.getRegisterMask(Mask));
4667
4668 if (SDValue Token = CLI.ConvergenceControlToken) {
4670 GlueOps.push_back(Token);
4671 if (InGlue)
4672 GlueOps.push_back(InGlue);
4673
4674 InGlue = SDValue(DAG.getMachineNode(TargetOpcode::CONVERGENCECTRL_GLUE, DL,
4675 MVT::Glue, GlueOps),
4676 0);
4677 }
4678
4679 if (InGlue)
4680 Ops.push_back(InGlue);
4681
4682 // If we're doing a tall call, use a TC_RETURN here rather than an
4683 // actual call instruction.
4684 if (IsTailCall) {
4685 MFI.setHasTailCall();
4686 unsigned OPC = AMDGPUISD::TC_RETURN;
4687 switch (CallConv) {
4689 OPC = AMDGPUISD::TC_RETURN_GFX;
4690 break;
4693 OPC = UsesDynamicVGPRs ? AMDGPUISD::TC_RETURN_CHAIN_DVGPR
4694 : AMDGPUISD::TC_RETURN_CHAIN;
4695 break;
4696 }
4697
4698 // If the caller is a whole wave function, we need to use a special opcode
4699 // so we can patch up EXEC.
4700 if (Info->isWholeWaveFunction())
4701 OPC = AMDGPUISD::TC_RETURN_GFX_WholeWave;
4702
4703 return DAG.getNode(OPC, DL, MVT::Other, Ops);
4704 }
4705
4706 // Returns a chain and a flag for retval copy to use.
4707 SDValue Call = DAG.getNode(AMDGPUISD::CALL, DL, {MVT::Other, MVT::Glue}, Ops);
4708 Chain = Call.getValue(0);
4709 InGlue = Call.getValue(1);
4710
4711 uint64_t CalleePopBytes = NumBytes;
4712 Chain = DAG.getCALLSEQ_END(Chain, 0, CalleePopBytes, InGlue, DL);
4713 if (!Ins.empty())
4714 InGlue = Chain.getValue(1);
4715
4716 // Handle result values, copying them out of physregs into vregs that we
4717 // return.
4718 return LowerCallResult(Chain, InGlue, CallConv, IsVarArg, Ins, DL, DAG,
4719 InVals, /*IsThisReturn=*/false, SDValue());
4720}
4721
4722// This is similar to the default implementation in ExpandDYNAMIC_STACKALLOC,
4723// except for:
4724// 1. Stack growth direction(default: downwards, AMDGPU: upwards), and
4725// 2. Scale size where, scale = wave-reduction(alloca-size) * wave-size
4727 SelectionDAG &DAG) const {
4728 const MachineFunction &MF = DAG.getMachineFunction();
4730
4731 SDLoc dl(Op);
4732 EVT VT = Op.getValueType();
4733 SDValue Chain = Op.getOperand(0);
4734 Register SPReg = Info->getStackPtrOffsetReg();
4735
4736 // Chain the dynamic stack allocation so that it doesn't modify the stack
4737 // pointer when other instructions are using the stack.
4738 Chain = DAG.getCALLSEQ_START(Chain, 0, 0, dl);
4739
4740 SDValue Size = Op.getOperand(1);
4741 SDValue BaseAddr = DAG.getCopyFromReg(Chain, dl, SPReg, VT);
4742 Align Alignment = cast<ConstantSDNode>(Op.getOperand(2))->getAlignValue();
4743
4744 const TargetFrameLowering *TFL = Subtarget->getFrameLowering();
4746 "Stack grows upwards for AMDGPU");
4747
4748 Chain = BaseAddr.getValue(1);
4749 // When using flat-scratch, the stack offset is unscaled.
4750 const bool HasFlatScratch = Subtarget->hasFlatScratchEnabled();
4751 const unsigned WavefrontSizeLog2 = Subtarget->getWavefrontSizeLog2();
4752
4753 Align StackAlign = TFL->getStackAlign();
4754 if (Alignment > StackAlign) {
4755 uint64_t ScaledAlignment = Alignment.value()
4756 << (HasFlatScratch ? 0 : WavefrontSizeLog2);
4757 uint64_t StackAlignMask = ScaledAlignment - 1;
4758 SDValue TmpAddr = DAG.getNode(ISD::ADD, dl, VT, BaseAddr,
4759 DAG.getConstant(StackAlignMask, dl, VT));
4760 BaseAddr = DAG.getNode(ISD::AND, dl, VT, TmpAddr,
4761 DAG.getSignedConstant(-ScaledAlignment, dl, VT));
4762 }
4763
4764 assert(Size.getValueType() == MVT::i32 && "Size must be 32-bit");
4765 SDValue NewSP;
4767 // Increase the stack pointer by the size of the alloca.
4768 // If not using flat-scratch, we have to scale the size by the wave-size.
4769 SDValue ScaledSize =
4770 HasFlatScratch
4771 ? Size
4772 : DAG.getNode(ISD::SHL, dl, VT, Size,
4773 DAG.getConstant(WavefrontSizeLog2, dl, MVT::i32));
4774 NewSP = DAG.getNode(ISD::ADD, dl, VT, BaseAddr, ScaledSize); // Value
4775 } else {
4776 // For dynamic sized alloca, perform wave-wide reduction to get max of
4777 // alloca size(divergent), and then scale it (when not using flat-scratch)
4778 // by wave-size.
4779 SDValue WaveReduction =
4780 DAG.getTargetConstant(Intrinsic::amdgcn_wave_reduce_umax, dl, MVT::i32);
4781 Size = DAG.getNode(ISD::INTRINSIC_WO_CHAIN, dl, MVT::i32, WaveReduction,
4782 Size, DAG.getTargetConstant(0, dl, MVT::i32));
4783 SDValue ScaledSize = Size;
4784 if (!HasFlatScratch) {
4785 ScaledSize =
4786 DAG.getNode(ISD::SHL, dl, VT, Size,
4787 DAG.getConstant(WavefrontSizeLog2, dl, MVT::i32));
4788 }
4789 NewSP =
4790 DAG.getNode(ISD::ADD, dl, VT, BaseAddr, ScaledSize); // Value in vgpr.
4791 SDValue ReadFirstLaneID =
4792 DAG.getTargetConstant(Intrinsic::amdgcn_readfirstlane, dl, MVT::i32);
4793 NewSP = DAG.getNode(ISD::INTRINSIC_WO_CHAIN, dl, MVT::i32, ReadFirstLaneID,
4794 NewSP);
4795 }
4796
4797 Chain = DAG.getCopyToReg(Chain, dl, SPReg, NewSP); // Output chain
4798 SDValue CallSeqEnd = DAG.getCALLSEQ_END(Chain, 0, 0, SDValue(), dl);
4799
4800 return DAG.getMergeValues({BaseAddr, CallSeqEnd}, dl);
4801}
4802
4804 if (Op.getValueType() != MVT::i32)
4805 return Op; // Defer to cannot select error.
4806
4808 SDLoc SL(Op);
4809
4810 SDValue CopyFromSP = DAG.getCopyFromReg(Op->getOperand(0), SL, SP, MVT::i32);
4811
4812 // Convert from wave uniform to swizzled vector address. This should protect
4813 // from any edge cases where the stacksave result isn't directly used with
4814 // stackrestore.
4815 SDValue VectorAddress =
4816 DAG.getNode(AMDGPUISD::WAVE_ADDRESS, SL, MVT::i32, CopyFromSP);
4817 return DAG.getMergeValues({VectorAddress, CopyFromSP.getValue(1)}, SL);
4818}
4819
4821 SelectionDAG &DAG) const {
4822 SDLoc SL(Op);
4823 assert(Op.getValueType() == MVT::i32);
4824
4825 uint32_t BothRoundHwReg =
4827 SDValue GetRoundBothImm = DAG.getTargetConstant(BothRoundHwReg, SL, MVT::i32);
4828
4829 SDValue IntrinID =
4830 DAG.getTargetConstant(Intrinsic::amdgcn_s_getreg, SL, MVT::i32);
4831 SDValue GetReg = DAG.getNode(ISD::INTRINSIC_W_CHAIN, SL, Op->getVTList(),
4832 Op.getOperand(0), IntrinID, GetRoundBothImm);
4833
4834 // There are two rounding modes, one for f32 and one for f64/f16. We only
4835 // report in the standard value range if both are the same.
4836 //
4837 // The raw values also differ from the expected FLT_ROUNDS values. Nearest
4838 // ties away from zero is not supported, and the other values are rotated by
4839 // 1.
4840 //
4841 // If the two rounding modes are not the same, report a target defined value.
4842
4843 // Mode register rounding mode fields:
4844 //
4845 // [1:0] Single-precision round mode.
4846 // [3:2] Double/Half-precision round mode.
4847 //
4848 // 0=nearest even; 1= +infinity; 2= -infinity, 3= toward zero.
4849 //
4850 // Hardware Spec
4851 // Toward-0 3 0
4852 // Nearest Even 0 1
4853 // +Inf 1 2
4854 // -Inf 2 3
4855 // NearestAway0 N/A 4
4856 //
4857 // We have to handle 16 permutations of a 4-bit value, so we create a 64-bit
4858 // table we can index by the raw hardware mode.
4859 //
4860 // (trunc (FltRoundConversionTable >> MODE.fp_round)) & 0xf
4861
4862 SDValue BitTable =
4864
4865 SDValue Two = DAG.getConstant(2, SL, MVT::i32);
4866 SDValue RoundModeTimesNumBits =
4867 DAG.getNode(ISD::SHL, SL, MVT::i32, GetReg, Two);
4868
4869 // TODO: We could possibly avoid a 64-bit shift and use a simpler table if we
4870 // knew only one mode was demanded.
4871 SDValue TableValue =
4872 DAG.getNode(ISD::SRL, SL, MVT::i64, BitTable, RoundModeTimesNumBits);
4873 SDValue TruncTable = DAG.getNode(ISD::TRUNCATE, SL, MVT::i32, TableValue);
4874
4875 SDValue EntryMask = DAG.getConstant(0xf, SL, MVT::i32);
4876 SDValue TableEntry =
4877 DAG.getNode(ISD::AND, SL, MVT::i32, TruncTable, EntryMask);
4878
4879 // There's a gap in the 4-bit encoded table and actual enum values, so offset
4880 // if it's an extended value.
4881 SDValue Four = DAG.getConstant(4, SL, MVT::i32);
4882 SDValue IsStandardValue =
4883 DAG.getSetCC(SL, MVT::i1, TableEntry, Four, ISD::SETULT);
4884 SDValue EnumOffset = DAG.getNode(ISD::ADD, SL, MVT::i32, TableEntry, Four);
4885 SDValue Result = DAG.getNode(ISD::SELECT, SL, MVT::i32, IsStandardValue,
4886 TableEntry, EnumOffset);
4887
4888 return DAG.getMergeValues({Result, GetReg.getValue(1)}, SL);
4889}
4890
4892 SelectionDAG &DAG) const {
4893 SDLoc SL(Op);
4894
4895 SDValue NewMode = Op.getOperand(1);
4896 assert(NewMode.getValueType() == MVT::i32);
4897
4898 // Index a table of 4-bit entries mapping from the C FLT_ROUNDS values to the
4899 // hardware MODE.fp_round values.
4900 if (auto *ConstMode = dyn_cast<ConstantSDNode>(NewMode)) {
4901 uint32_t ClampedVal = std::min(
4902 static_cast<uint32_t>(ConstMode->getZExtValue()),
4904 NewMode = DAG.getConstant(
4905 AMDGPU::decodeFltRoundToHWConversionTable(ClampedVal), SL, MVT::i32);
4906 } else {
4907 // If we know the input can only be one of the supported standard modes in
4908 // the range 0-3, we can use a simplified mapping to hardware values.
4909 KnownBits KB = DAG.computeKnownBits(NewMode);
4910 const bool UseReducedTable = KB.countMinLeadingZeros() >= 30;
4911 // The supported standard values are 0-3. The extended values start at 8. We
4912 // need to offset by 4 if the value is in the extended range.
4913
4914 if (UseReducedTable) {
4915 // Truncate to the low 32-bits.
4916 SDValue BitTable = DAG.getConstant(
4917 AMDGPU::FltRoundToHWConversionTable & 0xffff, SL, MVT::i32);
4918
4919 SDValue Two = DAG.getConstant(2, SL, MVT::i32);
4920 SDValue RoundModeTimesNumBits =
4921 DAG.getNode(ISD::SHL, SL, MVT::i32, NewMode, Two);
4922
4923 NewMode =
4924 DAG.getNode(ISD::SRL, SL, MVT::i32, BitTable, RoundModeTimesNumBits);
4925
4926 // TODO: SimplifyDemandedBits on the setreg source here can likely reduce
4927 // the table extracted bits into inline immediates.
4928 } else {
4929 // table_index = umin(value, value - 4)
4930 // MODE.fp_round = (bit_table >> (table_index << 2)) & 0xf
4931 SDValue BitTable =
4933
4934 SDValue Four = DAG.getConstant(4, SL, MVT::i32);
4935 SDValue OffsetEnum = DAG.getNode(ISD::SUB, SL, MVT::i32, NewMode, Four);
4936 SDValue IndexVal =
4937 DAG.getNode(ISD::UMIN, SL, MVT::i32, NewMode, OffsetEnum);
4938
4939 SDValue Two = DAG.getConstant(2, SL, MVT::i32);
4940 SDValue RoundModeTimesNumBits =
4941 DAG.getNode(ISD::SHL, SL, MVT::i32, IndexVal, Two);
4942
4943 SDValue TableValue =
4944 DAG.getNode(ISD::SRL, SL, MVT::i64, BitTable, RoundModeTimesNumBits);
4945 SDValue TruncTable = DAG.getNode(ISD::TRUNCATE, SL, MVT::i32, TableValue);
4946
4947 // No need to mask out the high bits since the setreg will ignore them
4948 // anyway.
4949 NewMode = TruncTable;
4950 }
4951
4952 // Insert a readfirstlane in case the value is a VGPR. We could do this
4953 // earlier and keep more operations scalar, but that interferes with
4954 // combining the source.
4955 SDValue ReadFirstLaneID =
4956 DAG.getTargetConstant(Intrinsic::amdgcn_readfirstlane, SL, MVT::i32);
4957 NewMode = DAG.getNode(ISD::INTRINSIC_WO_CHAIN, SL, MVT::i32,
4958 ReadFirstLaneID, NewMode);
4959 }
4960
4961 // N.B. The setreg will be later folded into s_round_mode on supported
4962 // targets.
4963 SDValue IntrinID =
4964 DAG.getTargetConstant(Intrinsic::amdgcn_s_setreg, SL, MVT::i32);
4965 uint32_t BothRoundHwReg =
4967 SDValue RoundBothImm = DAG.getTargetConstant(BothRoundHwReg, SL, MVT::i32);
4968
4969 SDValue SetReg =
4970 DAG.getNode(ISD::INTRINSIC_VOID, SL, Op->getVTList(), Op.getOperand(0),
4971 IntrinID, RoundBothImm, NewMode);
4972
4973 return SetReg;
4974}
4975
4977 if (Op->isDivergent() &&
4978 (!Subtarget->hasVmemPrefInsts() || !Op.getConstantOperandVal(4)))
4979 // Cannot do I$ prefetch with divergent pointer.
4980 return SDValue();
4981
4982 switch (cast<MemSDNode>(Op)->getAddressSpace()) {
4986 break;
4988 if (Subtarget->hasSafeSmemPrefetch())
4989 break;
4990 [[fallthrough]];
4991 default:
4992 return SDValue();
4993 }
4994
4995 // I$ prefetch
4996 if (!Subtarget->hasSafeSmemPrefetch() && !Op.getConstantOperandVal(4))
4997 return SDValue();
4998
4999 return Op;
5000}
5001
5002// Work around DAG legality rules only based on the result type.
5004 bool IsStrict = Op.getOpcode() == ISD::STRICT_FP_EXTEND;
5005 SDValue Src = Op.getOperand(IsStrict ? 1 : 0);
5006 EVT SrcVT = Src.getValueType();
5007
5008 if (SrcVT.getScalarType() != MVT::bf16)
5009 return Op;
5010
5011 SDLoc SL(Op);
5012 SDValue BitCast =
5013 DAG.getNode(ISD::BITCAST, SL, SrcVT.changeTypeToInteger(), Src);
5014
5015 EVT DstVT = Op.getValueType();
5016 if (IsStrict)
5017 llvm_unreachable("Need STRICT_BF16_TO_FP");
5018
5019 return DAG.getNode(ISD::BF16_TO_FP, SL, DstVT, BitCast);
5020}
5021
5023 SDLoc SL(Op);
5024 if (Op.getValueType() != MVT::i64)
5025 return Op;
5026
5027 uint32_t ModeHwReg =
5029 SDValue ModeHwRegImm = DAG.getTargetConstant(ModeHwReg, SL, MVT::i32);
5030 uint32_t TrapHwReg =
5032 SDValue TrapHwRegImm = DAG.getTargetConstant(TrapHwReg, SL, MVT::i32);
5033
5034 SDVTList VTList = DAG.getVTList(MVT::i32, MVT::Other);
5035 SDValue IntrinID =
5036 DAG.getTargetConstant(Intrinsic::amdgcn_s_getreg, SL, MVT::i32);
5037 SDValue GetModeReg = DAG.getNode(ISD::INTRINSIC_W_CHAIN, SL, VTList,
5038 Op.getOperand(0), IntrinID, ModeHwRegImm);
5039 SDValue GetTrapReg = DAG.getNode(ISD::INTRINSIC_W_CHAIN, SL, VTList,
5040 Op.getOperand(0), IntrinID, TrapHwRegImm);
5041 SDValue TokenReg =
5042 DAG.getNode(ISD::TokenFactor, SL, MVT::Other, GetModeReg.getValue(1),
5043 GetTrapReg.getValue(1));
5044
5045 SDValue CvtPtr =
5046 DAG.getNode(ISD::BUILD_VECTOR, SL, MVT::v2i32, GetModeReg, GetTrapReg);
5047 SDValue Result = DAG.getNode(ISD::BITCAST, SL, MVT::i64, CvtPtr);
5048
5049 return DAG.getMergeValues({Result, TokenReg}, SL);
5050}
5051
5053 SDLoc SL(Op);
5054 if (Op.getOperand(1).getValueType() != MVT::i64)
5055 return Op;
5056
5057 SDValue Input = DAG.getNode(ISD::BITCAST, SL, MVT::v2i32, Op.getOperand(1));
5058 SDValue NewModeReg = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, SL, MVT::i32, Input,
5059 DAG.getConstant(0, SL, MVT::i32));
5060 SDValue NewTrapReg = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, SL, MVT::i32, Input,
5061 DAG.getConstant(1, SL, MVT::i32));
5062
5063 SDValue ReadFirstLaneID =
5064 DAG.getTargetConstant(Intrinsic::amdgcn_readfirstlane, SL, MVT::i32);
5065 NewModeReg = DAG.getNode(ISD::INTRINSIC_WO_CHAIN, SL, MVT::i32,
5066 ReadFirstLaneID, NewModeReg);
5067 NewTrapReg = DAG.getNode(ISD::INTRINSIC_WO_CHAIN, SL, MVT::i32,
5068 ReadFirstLaneID, NewTrapReg);
5069
5070 unsigned ModeHwReg =
5072 SDValue ModeHwRegImm = DAG.getTargetConstant(ModeHwReg, SL, MVT::i32);
5073 unsigned TrapHwReg =
5075 SDValue TrapHwRegImm = DAG.getTargetConstant(TrapHwReg, SL, MVT::i32);
5076
5077 SDValue IntrinID =
5078 DAG.getTargetConstant(Intrinsic::amdgcn_s_setreg, SL, MVT::i32);
5079 SDValue SetModeReg =
5080 DAG.getNode(ISD::INTRINSIC_VOID, SL, MVT::Other, Op.getOperand(0),
5081 IntrinID, ModeHwRegImm, NewModeReg);
5082 SDValue SetTrapReg =
5083 DAG.getNode(ISD::INTRINSIC_VOID, SL, MVT::Other, Op.getOperand(0),
5084 IntrinID, TrapHwRegImm, NewTrapReg);
5085 return DAG.getNode(ISD::TokenFactor, SL, MVT::Other, SetTrapReg, SetModeReg);
5086}
5087
5089 const MachineFunction &MF) const {
5090 const Function &Fn = MF.getFunction();
5091
5093 .Case("m0", AMDGPU::M0)
5094 .Case("exec", AMDGPU::EXEC)
5095 .Case("exec_lo", AMDGPU::EXEC_LO)
5096 .Case("exec_hi", AMDGPU::EXEC_HI)
5097 .Case("flat_scratch", AMDGPU::FLAT_SCR)
5098 .Case("flat_scratch_lo", AMDGPU::FLAT_SCR_LO)
5099 .Case("flat_scratch_hi", AMDGPU::FLAT_SCR_HI)
5100 .Default(Register());
5101 if (!Reg)
5102 return Reg;
5103
5104 if (!Subtarget->hasFlatScrRegister() &&
5105 Subtarget->getRegisterInfo()->regsOverlap(Reg, AMDGPU::FLAT_SCR)) {
5106 Fn.getContext().emitError(Twine("invalid register \"" + StringRef(RegName) +
5107 "\" for subtarget."));
5108 }
5109
5110 switch (Reg) {
5111 case AMDGPU::M0:
5112 case AMDGPU::EXEC_LO:
5113 case AMDGPU::EXEC_HI:
5114 case AMDGPU::FLAT_SCR_LO:
5115 case AMDGPU::FLAT_SCR_HI:
5116 if (VT.getSizeInBits() == 32)
5117 return Reg;
5118 break;
5119 case AMDGPU::EXEC:
5120 case AMDGPU::FLAT_SCR:
5121 if (VT.getSizeInBits() == 64)
5122 return Reg;
5123 break;
5124 default:
5125 llvm_unreachable("missing register type checking");
5126 }
5127
5129 Twine("invalid type for register \"" + StringRef(RegName) + "\"."));
5130}
5131
5132// If kill is not the last instruction, split the block so kill is always a
5133// proper terminator.
5136 MachineBasicBlock *BB) const {
5137 MachineBasicBlock *SplitBB = BB->splitAt(MI, /*UpdateLiveIns=*/true);
5139 MI.setDesc(TII->getKillTerminatorFromPseudo(MI.getOpcode()));
5140 return SplitBB;
5141}
5142
5143// Split block \p MBB at \p MI, as to insert a loop. If \p InstInLoop is true,
5144// \p MI will be the only instruction in the loop body block. Otherwise, it will
5145// be the first instruction in the remainder block.
5146//
5147/// \returns { LoopBody, Remainder }
5148static std::pair<MachineBasicBlock *, MachineBasicBlock *>
5150 MachineFunction *MF = MBB.getParent();
5152
5153 // To insert the loop we need to split the block. Move everything after this
5154 // point to a new block, and insert a new empty block between the two.
5156 MachineBasicBlock *RemainderBB = MF->CreateMachineBasicBlock();
5158 ++MBBI;
5159
5160 MF->insert(MBBI, LoopBB);
5161 MF->insert(MBBI, RemainderBB);
5162
5163 LoopBB->addSuccessor(LoopBB);
5164 LoopBB->addSuccessor(RemainderBB);
5165
5166 // Move the rest of the block into a new block.
5167 RemainderBB->transferSuccessorsAndUpdatePHIs(&MBB);
5168
5169 if (InstInLoop) {
5170 auto Next = std::next(I);
5171
5172 // Move instruction to loop body.
5173 LoopBB->splice(LoopBB->begin(), &MBB, I, Next);
5174
5175 // Move the rest of the block.
5176 RemainderBB->splice(RemainderBB->begin(), &MBB, Next, MBB.end());
5177 } else {
5178 RemainderBB->splice(RemainderBB->begin(), &MBB, I, MBB.end());
5179 }
5180
5181 MBB.addSuccessor(LoopBB);
5182
5183 return std::pair(LoopBB, RemainderBB);
5184}
5185
5186/// Insert \p MI into a BUNDLE with an S_WAITCNT 0 immediately following it.
5188 MachineBasicBlock *MBB = MI.getParent();
5190 auto I = MI.getIterator();
5191 auto E = std::next(I);
5192
5193 // clang-format off
5194 BuildMI(*MBB, E, MI.getDebugLoc(), TII->get(AMDGPU::S_WAITCNT))
5195 .addImm(0);
5196 // clang-format on
5197
5198 MIBundleBuilder Bundler(*MBB, I, E);
5199 finalizeBundle(*MBB, Bundler.begin());
5200}
5201
5204 MachineBasicBlock *BB) const {
5205 const DebugLoc &DL = MI.getDebugLoc();
5206
5208
5210
5211 // Apparently kill flags are only valid if the def is in the same block?
5212 if (MachineOperand *Src = TII->getNamedOperand(MI, AMDGPU::OpName::data0))
5213 Src->setIsKill(false);
5214
5215 auto [LoopBB, RemainderBB] = splitBlockForLoop(MI, *BB, true);
5216
5217 MachineBasicBlock::iterator I = LoopBB->end();
5218
5219 const unsigned EncodedReg = AMDGPU::Hwreg::HwregEncoding::encode(
5221
5222 // Clear TRAP_STS.MEM_VIOL
5223 BuildMI(*LoopBB, LoopBB->begin(), DL, TII->get(AMDGPU::S_SETREG_IMM32_B32))
5224 .addImm(0)
5225 .addImm(EncodedReg);
5226
5228
5229 Register Reg = MRI.createVirtualRegister(&AMDGPU::SReg_32_XM0RegClass);
5230
5231 // Load and check TRAP_STS.MEM_VIOL
5232 BuildMI(*LoopBB, I, DL, TII->get(AMDGPU::S_GETREG_B32), Reg)
5233 .addImm(EncodedReg);
5234
5235 // FIXME: Do we need to use an isel pseudo that may clobber scc?
5236 BuildMI(*LoopBB, I, DL, TII->get(AMDGPU::S_CMP_LG_U32))
5237 .addReg(Reg, RegState::Kill)
5238 .addImm(0);
5239 // clang-format off
5240 BuildMI(*LoopBB, I, DL, TII->get(AMDGPU::S_CBRANCH_SCC1))
5241 .addMBB(LoopBB);
5242 // clang-format on
5243
5244 return RemainderBB;
5245}
5246
5247// Do a v_movrels_b32 or v_movreld_b32 for each unique value of \p IdxReg in the
5248// wavefront. If the value is uniform and just happens to be in a VGPR, this
5249// will only do one iteration. In the worst case, this will loop 64 times.
5250//
5251// TODO: Just use v_readlane_b32 if we know the VGPR has a uniform value.
5254 MachineBasicBlock &OrigBB, MachineBasicBlock &LoopBB,
5255 const DebugLoc &DL, const MachineOperand &Idx,
5256 unsigned InitReg, unsigned ResultReg, unsigned PhiReg,
5257 unsigned InitSaveExecReg, int Offset, bool UseGPRIdxMode,
5258 Register &SGPRIdxReg) {
5259
5260 MachineFunction *MF = OrigBB.getParent();
5261 const GCNSubtarget &ST = MF->getSubtarget<GCNSubtarget>();
5262 const SIRegisterInfo *TRI = ST.getRegisterInfo();
5265
5266 const TargetRegisterClass *BoolRC = TRI->getBoolRC();
5267 Register PhiExec = MRI.createVirtualRegister(BoolRC);
5268 Register NewExec = MRI.createVirtualRegister(BoolRC);
5269 Register CurrentIdxReg =
5270 MRI.createVirtualRegister(&AMDGPU::SReg_32_XM0RegClass);
5271 Register CondReg = MRI.createVirtualRegister(BoolRC);
5272
5273 BuildMI(LoopBB, I, DL, TII->get(TargetOpcode::PHI), PhiReg)
5274 .addReg(InitReg)
5275 .addMBB(&OrigBB)
5276 .addReg(ResultReg)
5277 .addMBB(&LoopBB);
5278
5279 BuildMI(LoopBB, I, DL, TII->get(TargetOpcode::PHI), PhiExec)
5280 .addReg(InitSaveExecReg)
5281 .addMBB(&OrigBB)
5282 .addReg(NewExec)
5283 .addMBB(&LoopBB);
5284
5285 // Read the next variant <- also loop target.
5286 BuildMI(LoopBB, I, DL, TII->get(AMDGPU::V_READFIRSTLANE_B32), CurrentIdxReg)
5287 .addReg(Idx.getReg(), getUndefRegState(Idx.isUndef()));
5288
5289 // Compare the just read M0 value to all possible Idx values.
5290 BuildMI(LoopBB, I, DL, TII->get(AMDGPU::V_CMP_EQ_U32_e64), CondReg)
5291 .addReg(CurrentIdxReg)
5292 .addReg(Idx.getReg(), {}, Idx.getSubReg());
5293
5294 // Update EXEC, save the original EXEC value to VCC.
5295 BuildMI(LoopBB, I, DL, TII->get(LMC.AndSaveExecOpc), NewExec)
5296 .addReg(CondReg, RegState::Kill);
5297
5298 MRI.setSimpleHint(NewExec, CondReg);
5299
5300 if (UseGPRIdxMode) {
5301 if (Offset == 0) {
5302 SGPRIdxReg = CurrentIdxReg;
5303 } else {
5304 SGPRIdxReg = MRI.createVirtualRegister(&AMDGPU::SGPR_32RegClass);
5305 BuildMI(LoopBB, I, DL, TII->get(AMDGPU::S_ADD_I32), SGPRIdxReg)
5306 .addReg(CurrentIdxReg, RegState::Kill)
5307 .addImm(Offset);
5308 }
5309 } else {
5310 // Move index from VCC into M0
5311 if (Offset == 0) {
5312 BuildMI(LoopBB, I, DL, TII->get(AMDGPU::COPY), AMDGPU::M0)
5313 .addReg(CurrentIdxReg, RegState::Kill);
5314 } else {
5315 BuildMI(LoopBB, I, DL, TII->get(AMDGPU::S_ADD_I32), AMDGPU::M0)
5316 .addReg(CurrentIdxReg, RegState::Kill)
5317 .addImm(Offset);
5318 }
5319 }
5320
5321 // Update EXEC, switch all done bits to 0 and all todo bits to 1.
5322 MachineInstr *InsertPt =
5323 BuildMI(LoopBB, I, DL, TII->get(LMC.XorTermOpc), LMC.ExecReg)
5324 .addReg(LMC.ExecReg)
5325 .addReg(NewExec);
5326
5327 // XXX - s_xor_b64 sets scc to 1 if the result is nonzero, so can we use
5328 // s_cbranch_scc0?
5329
5330 // Loop back to V_READFIRSTLANE_B32 if there are still variants to cover.
5331 // clang-format off
5332 BuildMI(LoopBB, I, DL, TII->get(AMDGPU::S_CBRANCH_EXECNZ))
5333 .addMBB(&LoopBB);
5334 // clang-format on
5335
5336 return InsertPt->getIterator();
5337}
5338
5339// This has slightly sub-optimal regalloc when the source vector is killed by
5340// the read. The register allocator does not understand that the kill is
5341// per-workitem, so is kept alive for the whole loop so we end up not re-using a
5342// subregister from it, using 1 more VGPR than necessary. This was saved when
5343// this was expanded after register allocation.
5346 unsigned InitResultReg, unsigned PhiReg, int Offset,
5347 bool UseGPRIdxMode, Register &SGPRIdxReg) {
5348 MachineFunction *MF = MBB.getParent();
5349 const GCNSubtarget &ST = MF->getSubtarget<GCNSubtarget>();
5350 const SIRegisterInfo *TRI = ST.getRegisterInfo();
5351 MachineRegisterInfo &MRI = MF->getRegInfo();
5352 const DebugLoc &DL = MI.getDebugLoc();
5354
5355 const auto *BoolXExecRC = TRI->getWaveMaskRegClass();
5356 Register DstReg = MI.getOperand(0).getReg();
5357 Register SaveExec = MRI.createVirtualRegister(BoolXExecRC);
5358 Register TmpExec = MRI.createVirtualRegister(BoolXExecRC);
5360
5361 BuildMI(MBB, I, DL, TII->get(TargetOpcode::IMPLICIT_DEF), TmpExec);
5362
5363 // Save the EXEC mask
5364 // clang-format off
5365 BuildMI(MBB, I, DL, TII->get(LMC.MovOpc), SaveExec)
5366 .addReg(LMC.ExecReg);
5367 // clang-format on
5368
5369 auto [LoopBB, RemainderBB] = splitBlockForLoop(MI, MBB, false);
5370
5371 const MachineOperand *Idx = TII->getNamedOperand(MI, AMDGPU::OpName::idx);
5372
5373 auto InsPt = emitLoadM0FromVGPRLoop(TII, MRI, MBB, *LoopBB, DL, *Idx,
5374 InitResultReg, DstReg, PhiReg, TmpExec,
5375 Offset, UseGPRIdxMode, SGPRIdxReg);
5376
5377 MachineBasicBlock *LandingPad = MF->CreateMachineBasicBlock();
5379 ++MBBI;
5380 MF->insert(MBBI, LandingPad);
5381 LoopBB->removeSuccessor(RemainderBB);
5382 LandingPad->addSuccessor(RemainderBB);
5383 LoopBB->addSuccessor(LandingPad);
5384 MachineBasicBlock::iterator First = LandingPad->begin();
5385 // clang-format off
5386 BuildMI(*LandingPad, First, DL, TII->get(LMC.MovOpc), LMC.ExecReg)
5387 .addReg(SaveExec);
5388 // clang-format on
5389
5390 return InsPt;
5391}
5392
5393// Returns subreg index, offset
5394static std::pair<unsigned, int>
5396 const TargetRegisterClass *SuperRC, unsigned VecReg,
5397 int Offset) {
5398 int NumElts = TRI.getRegSizeInBits(*SuperRC) / 32;
5399
5400 // Skip out of bounds offsets, or else we would end up using an undefined
5401 // register.
5402 if (Offset >= NumElts || Offset < 0)
5403 return std::pair(AMDGPU::sub0, Offset);
5404
5405 return std::pair(SIRegisterInfo::getSubRegFromChannel(Offset), 0);
5406}
5407
5410 int Offset) {
5411 MachineBasicBlock *MBB = MI.getParent();
5412 const DebugLoc &DL = MI.getDebugLoc();
5414
5415 const MachineOperand *Idx = TII->getNamedOperand(MI, AMDGPU::OpName::idx);
5416
5417 assert(Idx->getReg() != AMDGPU::NoRegister);
5418
5419 if (Offset == 0) {
5420 // clang-format off
5421 BuildMI(*MBB, I, DL, TII->get(AMDGPU::COPY), AMDGPU::M0)
5422 .add(*Idx);
5423 // clang-format on
5424 } else {
5425 BuildMI(*MBB, I, DL, TII->get(AMDGPU::S_ADD_I32), AMDGPU::M0)
5426 .add(*Idx)
5427 .addImm(Offset);
5428 }
5429}
5430
5433 int Offset) {
5434 MachineBasicBlock *MBB = MI.getParent();
5435 const DebugLoc &DL = MI.getDebugLoc();
5437
5438 const MachineOperand *Idx = TII->getNamedOperand(MI, AMDGPU::OpName::idx);
5439
5440 if (Offset == 0)
5441 return Idx->getReg();
5442
5443 Register Tmp = MRI.createVirtualRegister(&AMDGPU::SReg_32_XM0RegClass);
5444 BuildMI(*MBB, I, DL, TII->get(AMDGPU::S_ADD_I32), Tmp)
5445 .add(*Idx)
5446 .addImm(Offset);
5447 return Tmp;
5448}
5449
5452 const GCNSubtarget &ST) {
5453 const SIInstrInfo *TII = ST.getInstrInfo();
5454 const SIRegisterInfo &TRI = TII->getRegisterInfo();
5455 MachineFunction *MF = MBB.getParent();
5456 MachineRegisterInfo &MRI = MF->getRegInfo();
5457
5458 Register Dst = MI.getOperand(0).getReg();
5459 const MachineOperand *Idx = TII->getNamedOperand(MI, AMDGPU::OpName::idx);
5460 Register SrcReg = TII->getNamedOperand(MI, AMDGPU::OpName::src)->getReg();
5461 int Offset = TII->getNamedOperand(MI, AMDGPU::OpName::offset)->getImm();
5462
5463 const TargetRegisterClass *VecRC = MRI.getRegClass(SrcReg);
5464 const TargetRegisterClass *IdxRC = MRI.getRegClass(Idx->getReg());
5465
5466 unsigned SubReg;
5467 std::tie(SubReg, Offset) =
5468 computeIndirectRegAndOffset(TRI, VecRC, SrcReg, Offset);
5469
5470 const bool UseGPRIdxMode = ST.useVGPRIndexMode();
5471
5472 // Check for a SGPR index.
5473 if (TII->getRegisterInfo().isSGPRClass(IdxRC)) {
5475 const DebugLoc &DL = MI.getDebugLoc();
5476
5477 if (UseGPRIdxMode) {
5478 // TODO: Look at the uses to avoid the copy. This may require rescheduling
5479 // to avoid interfering with other uses, so probably requires a new
5480 // optimization pass.
5481 Register Idx = getIndirectSGPRIdx(TII, MRI, MI, Offset);
5482
5483 const MCInstrDesc &GPRIDXDesc =
5484 TII->getIndirectGPRIDXPseudo(TRI.getRegSizeInBits(*VecRC), true);
5485 BuildMI(MBB, I, DL, GPRIDXDesc, Dst)
5486 .addReg(SrcReg)
5487 .addReg(Idx)
5488 .addImm(SubReg);
5489 } else {
5491
5492 BuildMI(MBB, I, DL, TII->get(AMDGPU::V_MOVRELS_B32_e32), Dst)
5493 .addReg(SrcReg, {}, SubReg)
5494 .addReg(SrcReg, RegState::Implicit);
5495 }
5496
5497 MI.eraseFromParent();
5498
5499 return &MBB;
5500 }
5501
5502 // Control flow needs to be inserted if indexing with a VGPR.
5503 const DebugLoc &DL = MI.getDebugLoc();
5505
5506 Register PhiReg = MRI.createVirtualRegister(&AMDGPU::VGPR_32RegClass);
5507 Register InitReg = MRI.createVirtualRegister(&AMDGPU::VGPR_32RegClass);
5508
5509 BuildMI(MBB, I, DL, TII->get(TargetOpcode::IMPLICIT_DEF), InitReg);
5510
5511 Register SGPRIdxReg;
5512 auto InsPt = loadM0FromVGPR(TII, MBB, MI, InitReg, PhiReg, Offset,
5513 UseGPRIdxMode, SGPRIdxReg);
5514
5515 MachineBasicBlock *LoopBB = InsPt->getParent();
5516
5517 if (UseGPRIdxMode) {
5518 const MCInstrDesc &GPRIDXDesc =
5519 TII->getIndirectGPRIDXPseudo(TRI.getRegSizeInBits(*VecRC), true);
5520
5521 BuildMI(*LoopBB, InsPt, DL, GPRIDXDesc, Dst)
5522 .addReg(SrcReg)
5523 .addReg(SGPRIdxReg)
5524 .addImm(SubReg);
5525 } else {
5526 BuildMI(*LoopBB, InsPt, DL, TII->get(AMDGPU::V_MOVRELS_B32_e32), Dst)
5527 .addReg(SrcReg, {}, SubReg)
5528 .addReg(SrcReg, RegState::Implicit);
5529 }
5530
5531 MI.eraseFromParent();
5532
5533 return LoopBB;
5534}
5535
5538 const GCNSubtarget &ST) {
5539 const SIInstrInfo *TII = ST.getInstrInfo();
5540 const SIRegisterInfo &TRI = TII->getRegisterInfo();
5541 MachineFunction *MF = MBB.getParent();
5542 MachineRegisterInfo &MRI = MF->getRegInfo();
5543
5544 Register Dst = MI.getOperand(0).getReg();
5545 const MachineOperand *SrcVec = TII->getNamedOperand(MI, AMDGPU::OpName::src);
5546 const MachineOperand *Idx = TII->getNamedOperand(MI, AMDGPU::OpName::idx);
5547 const MachineOperand *Val = TII->getNamedOperand(MI, AMDGPU::OpName::val);
5548 int Offset = TII->getNamedOperand(MI, AMDGPU::OpName::offset)->getImm();
5549 const TargetRegisterClass *VecRC = MRI.getRegClass(SrcVec->getReg());
5550 const TargetRegisterClass *IdxRC = MRI.getRegClass(Idx->getReg());
5551
5552 // This can be an immediate, but will be folded later.
5553 assert(Val->getReg());
5554
5555 unsigned SubReg;
5556 std::tie(SubReg, Offset) =
5557 computeIndirectRegAndOffset(TRI, VecRC, SrcVec->getReg(), Offset);
5558 const bool UseGPRIdxMode = ST.useVGPRIndexMode();
5559
5560 if (Idx->getReg() == AMDGPU::NoRegister) {
5562 const DebugLoc &DL = MI.getDebugLoc();
5563
5564 assert(Offset == 0);
5565
5566 BuildMI(MBB, I, DL, TII->get(TargetOpcode::INSERT_SUBREG), Dst)
5567 .add(*SrcVec)
5568 .add(*Val)
5569 .addImm(SubReg);
5570
5571 MI.eraseFromParent();
5572 return &MBB;
5573 }
5574
5575 // Check for a SGPR index.
5576 if (TII->getRegisterInfo().isSGPRClass(IdxRC)) {
5578 const DebugLoc &DL = MI.getDebugLoc();
5579
5580 if (UseGPRIdxMode) {
5581 Register Idx = getIndirectSGPRIdx(TII, MRI, MI, Offset);
5582
5583 const MCInstrDesc &GPRIDXDesc =
5584 TII->getIndirectGPRIDXPseudo(TRI.getRegSizeInBits(*VecRC), false);
5585 BuildMI(MBB, I, DL, GPRIDXDesc, Dst)
5586 .addReg(SrcVec->getReg())
5587 .add(*Val)
5588 .addReg(Idx)
5589 .addImm(SubReg);
5590 } else {
5592
5593 const MCInstrDesc &MovRelDesc = TII->getIndirectRegWriteMovRelPseudo(
5594 TRI.getRegSizeInBits(*VecRC), 32, false);
5595 BuildMI(MBB, I, DL, MovRelDesc, Dst)
5596 .addReg(SrcVec->getReg())
5597 .add(*Val)
5598 .addImm(SubReg);
5599 }
5600 MI.eraseFromParent();
5601 return &MBB;
5602 }
5603
5604 // Control flow needs to be inserted if indexing with a VGPR.
5605 if (Val->isReg())
5606 MRI.clearKillFlags(Val->getReg());
5607
5608 const DebugLoc &DL = MI.getDebugLoc();
5609
5610 Register PhiReg = MRI.createVirtualRegister(VecRC);
5611
5612 Register SGPRIdxReg;
5613 auto InsPt = loadM0FromVGPR(TII, MBB, MI, SrcVec->getReg(), PhiReg, Offset,
5614 UseGPRIdxMode, SGPRIdxReg);
5615 MachineBasicBlock *LoopBB = InsPt->getParent();
5616
5617 if (UseGPRIdxMode) {
5618 const MCInstrDesc &GPRIDXDesc =
5619 TII->getIndirectGPRIDXPseudo(TRI.getRegSizeInBits(*VecRC), false);
5620
5621 BuildMI(*LoopBB, InsPt, DL, GPRIDXDesc, Dst)
5622 .addReg(PhiReg)
5623 .add(*Val)
5624 .addReg(SGPRIdxReg)
5625 .addImm(SubReg);
5626 } else {
5627 const MCInstrDesc &MovRelDesc = TII->getIndirectRegWriteMovRelPseudo(
5628 TRI.getRegSizeInBits(*VecRC), 32, false);
5629 BuildMI(*LoopBB, InsPt, DL, MovRelDesc, Dst)
5630 .addReg(PhiReg)
5631 .add(*Val)
5632 .addImm(SubReg);
5633 }
5634
5635 MI.eraseFromParent();
5636 return LoopBB;
5637}
5638
5640 MachineBasicBlock *BB) {
5641 // For targets older than GFX12, we emit a sequence of 32-bit operations.
5642 // For GFX12, we emit s_add_u64 and s_sub_u64.
5643 MachineFunction *MF = BB->getParent();
5644 const SIInstrInfo *TII = MF->getSubtarget<GCNSubtarget>().getInstrInfo();
5645 const GCNSubtarget &ST = MF->getSubtarget<GCNSubtarget>();
5647 const DebugLoc &DL = MI.getDebugLoc();
5648 MachineOperand &Dest = MI.getOperand(0);
5649 MachineOperand &Src0 = MI.getOperand(1);
5650 MachineOperand &Src1 = MI.getOperand(2);
5651 bool IsAdd = (MI.getOpcode() == AMDGPU::S_ADD_U64_PSEUDO);
5652 if (ST.hasScalarAddSub64()) {
5653 unsigned Opc = IsAdd ? AMDGPU::S_ADD_U64 : AMDGPU::S_SUB_U64;
5654 // clang-format off
5655 BuildMI(*BB, MI, DL, TII->get(Opc), Dest.getReg())
5656 .add(Src0)
5657 .add(Src1);
5658 // clang-format on
5659 } else {
5660 const SIRegisterInfo *TRI = ST.getRegisterInfo();
5661 const TargetRegisterClass *BoolRC = TRI->getBoolRC();
5662
5663 Register DestSub0 = MRI.createVirtualRegister(&AMDGPU::SReg_32RegClass);
5664 Register DestSub1 = MRI.createVirtualRegister(&AMDGPU::SReg_32RegClass);
5665
5666 MachineOperand Src0Sub0 = TII->buildExtractSubRegOrImm(
5667 MI, MRI, Src0, BoolRC, AMDGPU::sub0, &AMDGPU::SReg_32RegClass);
5668 MachineOperand Src0Sub1 = TII->buildExtractSubRegOrImm(
5669 MI, MRI, Src0, BoolRC, AMDGPU::sub1, &AMDGPU::SReg_32RegClass);
5670
5671 MachineOperand Src1Sub0 = TII->buildExtractSubRegOrImm(
5672 MI, MRI, Src1, BoolRC, AMDGPU::sub0, &AMDGPU::SReg_32RegClass);
5673 MachineOperand Src1Sub1 = TII->buildExtractSubRegOrImm(
5674 MI, MRI, Src1, BoolRC, AMDGPU::sub1, &AMDGPU::SReg_32RegClass);
5675
5676 unsigned LoOpc = IsAdd ? AMDGPU::S_ADD_U32 : AMDGPU::S_SUB_U32;
5677 unsigned HiOpc = IsAdd ? AMDGPU::S_ADDC_U32 : AMDGPU::S_SUBB_U32;
5678 BuildMI(*BB, MI, DL, TII->get(LoOpc), DestSub0).add(Src0Sub0).add(Src1Sub0);
5679 BuildMI(*BB, MI, DL, TII->get(HiOpc), DestSub1).add(Src0Sub1).add(Src1Sub1);
5680 BuildMI(*BB, MI, DL, TII->get(TargetOpcode::REG_SEQUENCE), Dest.getReg())
5681 .addReg(DestSub0)
5682 .addImm(AMDGPU::sub0)
5683 .addReg(DestSub1)
5684 .addImm(AMDGPU::sub1);
5685 }
5686 MI.eraseFromParent();
5687 return BB;
5688}
5689
5691 MachineFunction *MF = BB->getParent();
5692 const GCNSubtarget &ST = MF->getSubtarget<GCNSubtarget>();
5693 const SIInstrInfo *TII = ST.getInstrInfo();
5694 const SIRegisterInfo *TRI = ST.getRegisterInfo();
5695 MachineRegisterInfo &MRI = MF->getRegInfo();
5696 const DebugLoc &DL = MI.getDebugLoc();
5697 Register Dst = MI.getOperand(0).getReg();
5698 const MachineOperand &Src0 = MI.getOperand(1);
5699 const MachineOperand &Src1 = MI.getOperand(2);
5700 Register SrcCond = MI.getOperand(3).getReg();
5701
5702 Register DstLo = MRI.createVirtualRegister(&AMDGPU::VGPR_32RegClass);
5703 Register DstHi = MRI.createVirtualRegister(&AMDGPU::VGPR_32RegClass);
5704 const TargetRegisterClass *CondRC = TRI->getWaveMaskRegClass();
5705 Register SrcCondCopy = MRI.createVirtualRegister(CondRC);
5706
5707 int Src0Idx =
5708 AMDGPU::getNamedOperandIdx(MI.getOpcode(), AMDGPU::OpName::src0);
5709 int Src1Idx =
5710 AMDGPU::getNamedOperandIdx(MI.getOpcode(), AMDGPU::OpName::src1);
5711 const TargetRegisterClass *Src0RC =
5712 TRI->getAllocatableClass(TII->getRegClass(MI.getDesc(), Src0Idx));
5713 const TargetRegisterClass *Src1RC =
5714 TRI->getAllocatableClass(TII->getRegClass(MI.getDesc(), Src1Idx));
5715
5716 const TargetRegisterClass *Src0SubRC =
5717 TRI->getSubRegisterClass(Src0RC, AMDGPU::sub0);
5718 const TargetRegisterClass *Src1SubRC =
5719 TRI->getSubRegisterClass(Src1RC, AMDGPU::sub1);
5720
5721 MachineOperand Src0Sub0 = TII->buildExtractSubRegOrImm(
5722 MI, MRI, Src0, Src0RC, AMDGPU::sub0, Src0SubRC);
5723 MachineOperand Src1Sub0 = TII->buildExtractSubRegOrImm(
5724 MI, MRI, Src1, Src1RC, AMDGPU::sub0, Src1SubRC);
5725
5726 MachineOperand Src0Sub1 = TII->buildExtractSubRegOrImm(
5727 MI, MRI, Src0, Src0RC, AMDGPU::sub1, Src0SubRC);
5728 MachineOperand Src1Sub1 = TII->buildExtractSubRegOrImm(
5729 MI, MRI, Src1, Src1RC, AMDGPU::sub1, Src1SubRC);
5730
5731 BuildMI(*BB, MI, DL, TII->get(AMDGPU::COPY), SrcCondCopy).addReg(SrcCond);
5732 BuildMI(*BB, MI, DL, TII->get(AMDGPU::V_CNDMASK_B32_e64), DstLo)
5733 .addImm(0)
5734 .add(Src0Sub0)
5735 .addImm(0)
5736 .add(Src1Sub0)
5737 .addReg(SrcCondCopy);
5738
5739 BuildMI(*BB, MI, DL, TII->get(AMDGPU::V_CNDMASK_B32_e64), DstHi)
5740 .addImm(0)
5741 .add(Src0Sub1)
5742 .addImm(0)
5743 .add(Src1Sub1)
5744 .addReg(SrcCondCopy);
5745
5746 BuildMI(*BB, MI, DL, TII->get(AMDGPU::REG_SEQUENCE), Dst)
5747 .addReg(DstLo)
5748 .addImm(AMDGPU::sub0)
5749 .addReg(DstHi)
5750 .addImm(AMDGPU::sub1);
5751 MI.eraseFromParent();
5752}
5753
5755 switch (Opc) {
5756 case AMDGPU::S_MIN_U32:
5757 return std::numeric_limits<uint32_t>::max();
5758 case AMDGPU::S_MIN_I32:
5759 return std::numeric_limits<int32_t>::max();
5760 case AMDGPU::S_MAX_U32:
5761 return std::numeric_limits<uint32_t>::min();
5762 case AMDGPU::S_MAX_I32:
5763 return std::numeric_limits<int32_t>::min();
5764 case AMDGPU::V_ADD_F32_e64: // -0.0
5765 return 0x80000000;
5766 case AMDGPU::V_SUB_F32_e64: // +0.0
5767 return 0x0;
5768 case AMDGPU::S_ADD_I32:
5769 case AMDGPU::S_SUB_I32:
5770 case AMDGPU::S_OR_B32:
5771 case AMDGPU::S_XOR_B32:
5772 return std::numeric_limits<uint32_t>::min();
5773 case AMDGPU::S_AND_B32:
5774 return std::numeric_limits<uint32_t>::max();
5775 case AMDGPU::V_MIN_F32_e64:
5776 case AMDGPU::V_MAX_F32_e64:
5777 return 0x7fc00000; // qNAN
5778 case AMDGPU::V_CMP_LT_U64_e64: // umin.u64
5779 return std::numeric_limits<uint64_t>::max();
5780 case AMDGPU::V_CMP_LT_I64_e64: // min.i64
5781 return std::numeric_limits<int64_t>::max();
5782 case AMDGPU::V_CMP_GT_U64_e64: // umax.u64
5783 return std::numeric_limits<uint64_t>::min();
5784 case AMDGPU::V_CMP_GT_I64_e64: // max.i64
5785 return std::numeric_limits<int64_t>::min();
5786 case AMDGPU::V_MIN_F64_e64:
5787 case AMDGPU::V_MAX_F64_e64:
5788 case AMDGPU::V_MIN_NUM_F64_e64:
5789 case AMDGPU::V_MAX_NUM_F64_e64:
5790 return 0x7FF8000000000000; // qNAN
5791 case AMDGPU::S_ADD_U64_PSEUDO:
5792 case AMDGPU::S_SUB_U64_PSEUDO:
5793 case AMDGPU::S_OR_B64:
5794 case AMDGPU::S_XOR_B64:
5795 return std::numeric_limits<uint64_t>::min();
5796 case AMDGPU::S_AND_B64:
5797 return std::numeric_limits<uint64_t>::max();
5798 case AMDGPU::V_ADD_F64_e64:
5799 case AMDGPU::V_ADD_F64_pseudo_e64:
5800 return 0x8000000000000000; // -0.0
5801 default:
5802 llvm_unreachable("Unexpected opcode in getIdentityValueForWaveReduction");
5803 }
5804}
5805
5806static bool is32bitWaveReduceOperation(unsigned Opc) {
5807 return Opc == AMDGPU::S_MIN_U32 || Opc == AMDGPU::S_MIN_I32 ||
5808 Opc == AMDGPU::S_MAX_U32 || Opc == AMDGPU::S_MAX_I32 ||
5809 Opc == AMDGPU::S_ADD_I32 || Opc == AMDGPU::S_SUB_I32 ||
5810 Opc == AMDGPU::S_AND_B32 || Opc == AMDGPU::S_OR_B32 ||
5811 Opc == AMDGPU::S_XOR_B32 || Opc == AMDGPU::V_MIN_F32_e64 ||
5812 Opc == AMDGPU::V_MAX_F32_e64 || Opc == AMDGPU::V_ADD_F32_e64 ||
5813 Opc == AMDGPU::V_SUB_F32_e64;
5814}
5815
5817 return Opc == AMDGPU::V_MIN_F32_e64 || Opc == AMDGPU::V_MAX_F32_e64 ||
5818 Opc == AMDGPU::V_ADD_F32_e64 || Opc == AMDGPU::V_SUB_F32_e64 ||
5819 Opc == AMDGPU::V_MIN_F64_e64 || Opc == AMDGPU::V_MAX_F64_e64 ||
5820 Opc == AMDGPU::V_MIN_NUM_F64_e64 || Opc == AMDGPU::V_MAX_NUM_F64_e64 ||
5821 Opc == AMDGPU::V_ADD_F64_e64 || Opc == AMDGPU::V_ADD_F64_pseudo_e64;
5822}
5823
5824static std::tuple<unsigned, unsigned>
5826 unsigned DPPOpc;
5827 switch (Opc) {
5828 case AMDGPU::S_MIN_U32:
5829 DPPOpc = AMDGPU::V_MIN_U32_dpp;
5830 break;
5831 case AMDGPU::S_MIN_I32:
5832 DPPOpc = AMDGPU::V_MIN_I32_dpp;
5833 break;
5834 case AMDGPU::S_MAX_U32:
5835 DPPOpc = AMDGPU::V_MAX_U32_dpp;
5836 break;
5837 case AMDGPU::S_MAX_I32:
5838 DPPOpc = AMDGPU::V_MAX_I32_dpp;
5839 break;
5840 case AMDGPU::S_ADD_I32:
5841 case AMDGPU::S_SUB_I32:
5842 DPPOpc = ST.hasAddNoCarryInsts() ? AMDGPU::V_ADD_U32_dpp
5843 : AMDGPU::V_ADD_CO_U32_dpp;
5844 break;
5845 case AMDGPU::S_AND_B32:
5846 DPPOpc = AMDGPU::V_AND_B32_dpp;
5847 break;
5848 case AMDGPU::S_OR_B32:
5849 DPPOpc = AMDGPU::V_OR_B32_dpp;
5850 break;
5851 case AMDGPU::S_XOR_B32:
5852 DPPOpc = AMDGPU::V_XOR_B32_dpp;
5853 break;
5854 case AMDGPU::V_ADD_F32_e64:
5855 case AMDGPU::V_SUB_F32_e64:
5856 DPPOpc = AMDGPU::V_ADD_F32_dpp;
5857 break;
5858 case AMDGPU::V_MIN_F32_e64:
5859 DPPOpc = AMDGPU::V_MIN_F32_dpp;
5860 break;
5861 case AMDGPU::V_MAX_F32_e64:
5862 DPPOpc = AMDGPU::V_MAX_F32_dpp;
5863 break;
5864 case AMDGPU::V_CMP_LT_U64_e64: // umin.u64
5865 case AMDGPU::V_CMP_LT_I64_e64: // min.i64
5866 case AMDGPU::V_CMP_GT_U64_e64: // umax.u64
5867 case AMDGPU::V_CMP_GT_I64_e64: // max.i64
5868 case AMDGPU::S_ADD_U64_PSEUDO:
5869 case AMDGPU::S_SUB_U64_PSEUDO:
5870 case AMDGPU::S_AND_B64:
5871 case AMDGPU::S_OR_B64:
5872 case AMDGPU::S_XOR_B64:
5873 case AMDGPU::V_MIN_NUM_F64_e64:
5874 case AMDGPU::V_MIN_F64_e64:
5875 case AMDGPU::V_MAX_NUM_F64_e64:
5876 case AMDGPU::V_MAX_F64_e64:
5877 case AMDGPU::V_ADD_F64_pseudo_e64:
5878 case AMDGPU::V_ADD_F64_e64:
5879 DPPOpc = AMDGPU::V_MOV_B64_DPP_PSEUDO;
5880 break;
5881 default:
5882 llvm_unreachable("unhandled lane op");
5883 }
5884 unsigned ClampOpc = Opc;
5885 if (!ST.getInstrInfo()->isVALU(Opc, /*AllowLDSDMA=*/true)) {
5886 if (Opc == AMDGPU::S_SUB_I32)
5887 ClampOpc = AMDGPU::S_ADD_I32;
5888 if (Opc == AMDGPU::S_ADD_U64_PSEUDO || Opc == AMDGPU::S_SUB_U64_PSEUDO)
5889 ClampOpc = AMDGPU::V_ADD_CO_U32_e64;
5890 else if (Opc == AMDGPU::S_AND_B64)
5891 ClampOpc = AMDGPU::V_AND_B32_e64;
5892 else if (Opc == AMDGPU::S_OR_B64)
5893 ClampOpc = AMDGPU::V_OR_B32_e64;
5894 else if (Opc == AMDGPU::S_XOR_B64)
5895 ClampOpc = AMDGPU::V_XOR_B32_e64;
5896 else
5897 ClampOpc = ST.getInstrInfo()->getVALUOp(ClampOpc);
5898 }
5899 return {DPPOpc, ClampOpc};
5900}
5901
5902static std::pair<Register, Register>
5904 const TargetRegisterClass *SrcRC, const GCNSubtarget &ST,
5905 MachineRegisterInfo &MRI) {
5906 const SIRegisterInfo *TRI = ST.getRegisterInfo();
5907 const SIInstrInfo *TII = ST.getInstrInfo();
5908 const TargetRegisterClass *SrcSubRC =
5909 TRI->getSubRegisterClass(SrcRC, AMDGPU::sub0);
5910 Register Op1L =
5911 TII->buildExtractSubReg(MI, MRI, Op, SrcRC, AMDGPU::sub0, SrcSubRC);
5912 Register Op1H =
5913 TII->buildExtractSubReg(MI, MRI, Op, SrcRC, AMDGPU::sub1, SrcSubRC);
5914 return {Op1L, Op1H};
5915}
5916
5919 const GCNSubtarget &ST,
5920 unsigned Opc) {
5922 const SIRegisterInfo *TRI = ST.getRegisterInfo();
5923 const DebugLoc &DL = MI.getDebugLoc();
5924 const SIInstrInfo *TII = ST.getInstrInfo();
5925
5926 // Reduction operations depend on whether the input operand is SGPR or VGPR.
5927 Register SrcReg = MI.getOperand(1).getReg();
5928 bool isSGPR = TRI->isSGPRClass(MRI.getRegClass(SrcReg));
5929 Register DstReg = MI.getOperand(0).getReg();
5930 unsigned Stratergy = static_cast<unsigned>(MI.getOperand(2).getImm());
5931 enum WAVE_REDUCE_STRATEGY : unsigned { DEFAULT = 0, ITERATIVE = 1, DPP = 2 };
5932 MachineBasicBlock *RetBB = nullptr;
5933 unsigned MIOpc = MI.getOpcode();
5934 auto BuildRegSequence = [&](MachineBasicBlock &BB,
5936 Register Src0, Register Src1) {
5937 auto RegSequence =
5938 BuildMI(BB, MI, DL, TII->get(TargetOpcode::REG_SEQUENCE), Dst)
5939 .addReg(Src0)
5940 .addImm(AMDGPU::sub0)
5941 .addReg(Src1)
5942 .addImm(AMDGPU::sub1);
5943 return RegSequence;
5944 };
5945 if (isSGPR) {
5946 switch (Opc) {
5947 case AMDGPU::S_MIN_U32:
5948 case AMDGPU::S_MIN_I32:
5949 case AMDGPU::V_MIN_F32_e64:
5950 case AMDGPU::S_MAX_U32:
5951 case AMDGPU::S_MAX_I32:
5952 case AMDGPU::V_MAX_F32_e64:
5953 case AMDGPU::S_AND_B32:
5954 case AMDGPU::S_OR_B32: {
5955 // Idempotent operations.
5956 BuildMI(BB, MI, DL, TII->get(AMDGPU::S_MOV_B32), DstReg).addReg(SrcReg);
5957 RetBB = &BB;
5958 break;
5959 }
5960 case AMDGPU::V_CMP_LT_U64_e64: // umin
5961 case AMDGPU::V_CMP_LT_I64_e64: // min
5962 case AMDGPU::V_CMP_GT_U64_e64: // umax
5963 case AMDGPU::V_CMP_GT_I64_e64: // max
5964 case AMDGPU::V_MIN_F64_e64:
5965 case AMDGPU::V_MIN_NUM_F64_e64:
5966 case AMDGPU::V_MAX_F64_e64:
5967 case AMDGPU::V_MAX_NUM_F64_e64:
5968 case AMDGPU::S_AND_B64:
5969 case AMDGPU::S_OR_B64: {
5970 // Idempotent operations.
5971 BuildMI(BB, MI, DL, TII->get(AMDGPU::S_MOV_B64), DstReg).addReg(SrcReg);
5972 RetBB = &BB;
5973 break;
5974 }
5975 case AMDGPU::S_XOR_B32:
5976 case AMDGPU::S_XOR_B64:
5977 case AMDGPU::S_ADD_I32:
5978 case AMDGPU::S_ADD_U64_PSEUDO:
5979 case AMDGPU::V_ADD_F32_e64:
5980 case AMDGPU::V_ADD_F64_e64:
5981 case AMDGPU::V_ADD_F64_pseudo_e64:
5982 case AMDGPU::S_SUB_I32:
5983 case AMDGPU::S_SUB_U64_PSEUDO:
5984 case AMDGPU::V_SUB_F32_e64: {
5985 const TargetRegisterClass *WaveMaskRegClass = TRI->getWaveMaskRegClass();
5986 const TargetRegisterClass *DstRegClass = MRI.getRegClass(DstReg);
5987 Register ExecMask = MRI.createVirtualRegister(WaveMaskRegClass);
5988 Register NumActiveLanes =
5989 MRI.createVirtualRegister(&AMDGPU::SReg_32RegClass);
5990
5991 bool IsWave32 = ST.isWave32();
5992 unsigned MovOpc = IsWave32 ? AMDGPU::S_MOV_B32 : AMDGPU::S_MOV_B64;
5993 MCRegister ExecReg = IsWave32 ? AMDGPU::EXEC_LO : AMDGPU::EXEC;
5994 unsigned BitCountOpc =
5995 IsWave32 ? AMDGPU::S_BCNT1_I32_B32 : AMDGPU::S_BCNT1_I32_B64;
5996
5997 BuildMI(BB, MI, DL, TII->get(MovOpc), ExecMask).addReg(ExecReg);
5998
5999 auto NewAccumulator =
6000 BuildMI(BB, MI, DL, TII->get(BitCountOpc), NumActiveLanes)
6001 .addReg(ExecMask);
6002
6003 switch (Opc) {
6004 case AMDGPU::S_XOR_B32:
6005 case AMDGPU::S_XOR_B64: {
6006 // Performing an XOR operation on a uniform value
6007 // depends on the parity of the number of active lanes.
6008 // For even parity, the result will be 0, for odd
6009 // parity the result will be the same as the input value.
6010 Register ParityRegister =
6011 MRI.createVirtualRegister(&AMDGPU::SReg_32RegClass);
6012
6013 BuildMI(BB, MI, DL, TII->get(AMDGPU::S_AND_B32), ParityRegister)
6014 .addReg(NewAccumulator->getOperand(0).getReg())
6015 .addImm(1)
6016 .setOperandDead(3); // Dead scc
6017 if (Opc == AMDGPU::S_XOR_B32) {
6018 BuildMI(BB, MI, DL, TII->get(AMDGPU::S_MUL_I32), DstReg)
6019 .addReg(SrcReg)
6020 .addReg(ParityRegister);
6021 } else {
6022 Register DestSub0 =
6023 MRI.createVirtualRegister(&AMDGPU::SReg_32RegClass);
6024 Register DestSub1 =
6025 MRI.createVirtualRegister(&AMDGPU::SReg_32RegClass);
6026 auto [Op1L, Op1H] = ExtractSubRegs(MI, MI.getOperand(1),
6027 MRI.getRegClass(SrcReg), ST, MRI);
6028 BuildMI(BB, MI, DL, TII->get(AMDGPU::S_MUL_I32), DestSub0)
6029 .addReg(Op1L)
6030 .addReg(ParityRegister);
6031 BuildMI(BB, MI, DL, TII->get(AMDGPU::S_MUL_I32), DestSub1)
6032 .addReg(Op1H)
6033 .addReg(ParityRegister);
6034 BuildRegSequence(BB, MI, DstReg, DestSub0, DestSub1);
6035 }
6036 break;
6037 }
6038 case AMDGPU::S_SUB_I32: {
6039 Register NegatedVal = MRI.createVirtualRegister(DstRegClass);
6040
6041 // Take the negation of the source operand.
6042 BuildMI(BB, MI, DL, TII->get(AMDGPU::S_SUB_I32), NegatedVal)
6043 .addImm(0)
6044 .addReg(SrcReg);
6045 BuildMI(BB, MI, DL, TII->get(AMDGPU::S_MUL_I32), DstReg)
6046 .addReg(NegatedVal)
6047 .addReg(NewAccumulator->getOperand(0).getReg());
6048 break;
6049 }
6050 case AMDGPU::S_ADD_I32: {
6051 BuildMI(BB, MI, DL, TII->get(AMDGPU::S_MUL_I32), DstReg)
6052 .addReg(SrcReg)
6053 .addReg(NewAccumulator->getOperand(0).getReg());
6054 break;
6055 }
6056 case AMDGPU::S_ADD_U64_PSEUDO:
6057 case AMDGPU::S_SUB_U64_PSEUDO: {
6058 Register DestSub0 = MRI.createVirtualRegister(&AMDGPU::SReg_32RegClass);
6059 Register DestSub1 = MRI.createVirtualRegister(&AMDGPU::SReg_32RegClass);
6060 Register Op1H_Op0L_Reg =
6061 MRI.createVirtualRegister(&AMDGPU::SReg_32RegClass);
6062 Register Op1L_Op0H_Reg =
6063 MRI.createVirtualRegister(&AMDGPU::SReg_32RegClass);
6064 Register CarryReg =
6065 MRI.createVirtualRegister(&AMDGPU::SReg_32_XM0RegClass);
6066 Register AddReg = MRI.createVirtualRegister(&AMDGPU::SReg_32RegClass);
6067 Register NegatedValLo =
6068 MRI.createVirtualRegister(&AMDGPU::SReg_32RegClass);
6069 Register NegatedValHi =
6070 MRI.createVirtualRegister(&AMDGPU::SReg_32RegClass);
6071 auto [Op1L, Op1H] = ExtractSubRegs(MI, MI.getOperand(1),
6072 MRI.getRegClass(SrcReg), ST, MRI);
6073 if (Opc == AMDGPU::S_SUB_U64_PSEUDO) {
6074 BuildMI(BB, MI, DL, TII->get(AMDGPU::S_SUB_I32), NegatedValLo)
6075 .addImm(0)
6076 .addReg(NewAccumulator->getOperand(0).getReg())
6077 .setOperandDead(3); // Dead scc
6078 BuildMI(BB, MI, DL, TII->get(AMDGPU::S_ASHR_I32), NegatedValHi)
6079 .addReg(NegatedValLo)
6080 .addImm(31)
6081 .setOperandDead(3); // Dead scc
6082 BuildMI(BB, MI, DL, TII->get(AMDGPU::S_MUL_I32), Op1L_Op0H_Reg)
6083 .addReg(Op1L)
6084 .addReg(NegatedValHi);
6085 }
6086 Register LowOpcode = Opc == AMDGPU::S_SUB_U64_PSEUDO
6087 ? NegatedValLo
6088 : NewAccumulator->getOperand(0).getReg();
6089 BuildMI(BB, MI, DL, TII->get(AMDGPU::S_MUL_I32), DestSub0)
6090 .addReg(Op1L)
6091 .addReg(LowOpcode);
6092 if (ST.hasScalarMulHiInsts()) {
6093 BuildMI(BB, MI, DL, TII->get(AMDGPU::S_MUL_HI_U32), CarryReg)
6094 .addReg(Op1L)
6095 .addReg(LowOpcode);
6096 } else {
6097 Register VCarryReg =
6098 MRI.createVirtualRegister(&AMDGPU::VGPR_32RegClass);
6099 Register LowOpVGPR =
6100 MRI.createVirtualRegister(&AMDGPU::VGPR_32RegClass);
6101 BuildMI(BB, MI, DL, TII->get(AMDGPU::COPY), LowOpVGPR)
6102 .addReg(LowOpcode);
6103 BuildMI(BB, MI, DL, TII->get(AMDGPU::V_MUL_HI_U32_e64), VCarryReg)
6104 .addReg(Op1L)
6105 .addReg(LowOpVGPR);
6106 BuildMI(BB, MI, DL, TII->get(AMDGPU::V_READFIRSTLANE_B32), CarryReg)
6107 .addReg(VCarryReg);
6108 }
6109 BuildMI(BB, MI, DL, TII->get(AMDGPU::S_MUL_I32), Op1H_Op0L_Reg)
6110 .addReg(Op1H)
6111 .addReg(LowOpcode);
6112
6113 Register HiVal = Opc == AMDGPU::S_SUB_U64_PSEUDO ? AddReg : DestSub1;
6114 BuildMI(BB, MI, DL, TII->get(AMDGPU::S_ADD_U32), HiVal)
6115 .addReg(CarryReg)
6116 .addReg(Op1H_Op0L_Reg)
6117 .setOperandDead(3); // Dead scc
6118
6119 if (Opc == AMDGPU::S_SUB_U64_PSEUDO) {
6120 BuildMI(BB, MI, DL, TII->get(AMDGPU::S_ADD_U32), DestSub1)
6121 .addReg(HiVal)
6122 .addReg(Op1L_Op0H_Reg)
6123 .setOperandDead(3); // Dead scc
6124 }
6125 BuildRegSequence(BB, MI, DstReg, DestSub0, DestSub1);
6126 break;
6127 }
6128 case AMDGPU::V_ADD_F32_e64:
6129 case AMDGPU::V_ADD_F64_e64:
6130 case AMDGPU::V_ADD_F64_pseudo_e64:
6131 case AMDGPU::V_SUB_F32_e64: {
6132 bool is32BitOpc = is32bitWaveReduceOperation(Opc);
6133 const TargetRegisterClass *VregRC = TII->getRegClass(TII->get(Opc), 0);
6134 Register ActiveLanesVreg = MRI.createVirtualRegister(VregRC);
6135 Register DstVreg = MRI.createVirtualRegister(VregRC);
6136 // Get number of active lanes as a float val.
6137 BuildMI(BB, MI, DL,
6138 TII->get(is32BitOpc ? AMDGPU::V_CVT_F32_I32_e64
6139 : AMDGPU::V_CVT_F64_I32_e64),
6140 ActiveLanesVreg)
6141 .addReg(NewAccumulator->getOperand(0).getReg())
6142 .addImm(0) // clamp
6143 .addImm(0); // output-modifier
6144
6145 // Take negation of input for SUB reduction
6146 unsigned srcMod = (MIOpc == AMDGPU::WAVE_REDUCE_FSUB_PSEUDO_F32 ||
6147 MIOpc == AMDGPU::WAVE_REDUCE_FSUB_PSEUDO_F64)
6150 unsigned MulOpc = is32BitOpc ? AMDGPU::V_MUL_F32_e64
6151 : ST.getGeneration() >= AMDGPUSubtarget::GFX12
6152 ? AMDGPU::V_MUL_F64_pseudo_e64
6153 : AMDGPU::V_MUL_F64_e64;
6154 auto DestVregInst = BuildMI(BB, MI, DL, TII->get(MulOpc),
6155 DstVreg)
6156 .addImm(srcMod) // src0 modifier
6157 .addReg(SrcReg)
6158 .addImm(SISrcMods::NONE) // src1 modifier
6159 .addReg(ActiveLanesVreg)
6160 .addImm(SISrcMods::NONE) // clamp
6161 .addImm(SISrcMods::NONE); // output-mod
6162 if (is32BitOpc) {
6163 BuildMI(BB, MI, DL, TII->get(AMDGPU::V_READFIRSTLANE_B32), DstReg)
6164 .addReg(DstVreg);
6165 } else {
6166 Register LaneValueLoReg =
6167 MRI.createVirtualRegister(&AMDGPU::SReg_32_XM0RegClass);
6168 Register LaneValueHiReg =
6169 MRI.createVirtualRegister(&AMDGPU::SReg_32_XM0RegClass);
6170 auto [Op1L, Op1H] =
6171 ExtractSubRegs(MI, DestVregInst->getOperand(0), VregRC, ST, MRI);
6172 // lane value input should be in an sgpr
6173 BuildMI(BB, MI, DL, TII->get(AMDGPU::V_READFIRSTLANE_B32),
6174 LaneValueLoReg)
6175 .addReg(Op1L);
6176 BuildMI(BB, MI, DL, TII->get(AMDGPU::V_READFIRSTLANE_B32),
6177 LaneValueHiReg)
6178 .addReg(Op1H);
6179 NewAccumulator =
6180 BuildRegSequence(BB, MI, DstReg, LaneValueLoReg, LaneValueHiReg);
6181 }
6182 }
6183 }
6184 RetBB = &BB;
6185 }
6186 }
6187 } else {
6189 Register SrcReg = MI.getOperand(1).getReg();
6190 bool is32BitOpc = is32bitWaveReduceOperation(Opc);
6192 bool NeedsMovDPP = !is32BitOpc;
6193 // Create virtual registers required for lowering.
6194 const TargetRegisterClass *WaveMaskRegClass = TRI->getWaveMaskRegClass();
6195 const TargetRegisterClass *DstRegClass = MRI.getRegClass(DstReg);
6196 const TargetRegisterClass *SrcRegClass = MRI.getRegClass(SrcReg);
6197 bool IsWave32 = ST.isWave32();
6198 unsigned MovOpcForExec = IsWave32 ? AMDGPU::S_MOV_B32 : AMDGPU::S_MOV_B64;
6199 unsigned ExecReg = IsWave32 ? AMDGPU::EXEC_LO : AMDGPU::EXEC;
6200 if (Stratergy == WAVE_REDUCE_STRATEGY::ITERATIVE ||
6201 !ST.hasDPP()) { // If target doesn't support DPP operations, default to
6202 // iterative stratergy
6203
6204 // To reduce the VGPR using iterative approach, we need to iterate
6205 // over all the active lanes. Lowering consists of ComputeLoop,
6206 // which iterate over only active lanes. We use copy of EXEC register
6207 // as induction variable and every active lane modifies it using bitset0
6208 // so that we will get the next active lane for next iteration.
6209
6210 // Create Control flow for loop
6211 // Split MI's Machine Basic block into For loop
6212 auto [ComputeLoop, ComputeEnd] = splitBlockForLoop(MI, BB, true);
6213
6214 Register LoopIterator = MRI.createVirtualRegister(WaveMaskRegClass);
6215 Register IdentityValReg = MRI.createVirtualRegister(DstRegClass);
6216 Register AccumulatorReg = MRI.createVirtualRegister(DstRegClass);
6217 Register ActiveBitsReg = MRI.createVirtualRegister(WaveMaskRegClass);
6218 Register NewActiveBitsReg = MRI.createVirtualRegister(WaveMaskRegClass);
6219 Register FF1Reg = MRI.createVirtualRegister(&AMDGPU::SReg_32RegClass);
6220 Register LaneValueReg = MRI.createVirtualRegister(DstRegClass);
6221
6222 // Create initial values of induction variable from Exec, Accumulator and
6223 // insert branch instr to newly created ComputeBlock
6224 BuildMI(BB, I, DL, TII->get(MovOpcForExec), LoopIterator).addReg(ExecReg);
6225 uint64_t IdentityValue =
6226 MI.getOpcode() == AMDGPU::WAVE_REDUCE_FSUB_PSEUDO_F64
6227 ? 0x0 // +0.0 for double sub reduction
6229 BuildMI(BB, I, DL,
6230 TII->get(is32BitOpc ? AMDGPU::S_MOV_B32
6231 : AMDGPU::S_MOV_B64_IMM_PSEUDO),
6232 IdentityValReg)
6233 .addImm(IdentityValue);
6234 // clang-format off
6235 BuildMI(BB, I, DL, TII->get(AMDGPU::S_BRANCH))
6236 .addMBB(ComputeLoop);
6237 // clang-format on
6238
6239 // Start constructing ComputeLoop
6240 I = ComputeLoop->begin();
6241 auto Accumulator =
6242 BuildMI(*ComputeLoop, I, DL, TII->get(AMDGPU::PHI), AccumulatorReg)
6243 .addReg(IdentityValReg)
6244 .addMBB(&BB);
6245 auto ActiveBits =
6246 BuildMI(*ComputeLoop, I, DL, TII->get(AMDGPU::PHI), ActiveBitsReg)
6247 .addReg(LoopIterator)
6248 .addMBB(&BB);
6249
6250 I = ComputeLoop->end();
6251 MachineInstr *NewAccumulator;
6252 // Perform the computations
6253 unsigned SFFOpc =
6254 IsWave32 ? AMDGPU::S_FF1_I32_B32 : AMDGPU::S_FF1_I32_B64;
6255 BuildMI(*ComputeLoop, I, DL, TII->get(SFFOpc), FF1Reg)
6256 .addReg(ActiveBitsReg);
6257 if (is32BitOpc) {
6258 Register OpDstReg = DstReg;
6259 bool hasSrc0Modifier = AMDGPU::getNamedOperandIdx(
6260 Opc, AMDGPU::OpName::src0_modifiers) != -1;
6261 bool hasSrc1Modifier = AMDGPU::getNamedOperandIdx(
6262 Opc, AMDGPU::OpName::src1_modifiers) != -1;
6263 bool hasClamp =
6264 AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::clamp) != -1;
6265 bool hasOpSel =
6266 AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::op_sel) != -1;
6267 bool hasOMod =
6268 AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::omod) != -1;
6269 BuildMI(*ComputeLoop, I, DL, TII->get(AMDGPU::V_READLANE_B32),
6270 LaneValueReg)
6271 .addReg(SrcReg)
6272 .addReg(FF1Reg);
6273 if (ST.getInstrInfo()->isVALU(Opc, /*AllowLDSDMA=*/true)) {
6274 // Get the Lane Value in VGPR to avoid the Constant Bus Restriction
6275 Register LaneValVgpr = MRI.createVirtualRegister(SrcRegClass);
6276 Register VgprResultReg = MRI.createVirtualRegister(SrcRegClass);
6277 BuildMI(*ComputeLoop, I, DL, TII->get(AMDGPU::COPY), LaneValVgpr)
6278 .addReg(LaneValueReg);
6279 OpDstReg = VgprResultReg;
6280 LaneValueReg = LaneValVgpr;
6281 }
6282 auto OpInstr = BuildMI(*ComputeLoop, I, DL, TII->get(Opc), OpDstReg);
6283 if (hasSrc0Modifier)
6284 OpInstr.addImm(SISrcMods::NONE); // src0 modifier
6285 OpInstr.addReg(AccumulatorReg); // src0
6286 if (hasSrc1Modifier)
6287 OpInstr.addImm(SISrcMods::NONE); // src1 modifier
6288 OpInstr.addReg(LaneValueReg); // src1
6289 if (hasClamp)
6290 OpInstr.addImm(0); // clamp
6291 if (hasOpSel)
6292 OpInstr.addImm(0); // opsel
6293 if (hasOMod)
6294 OpInstr.addImm(0); // omod
6295 if (ST.getInstrInfo()->isVALU(Opc, /*AllowLDSDMA=*/true)) {
6296 BuildMI(*ComputeLoop, I, DL, TII->get(AMDGPU::V_READFIRSTLANE_B32),
6297 DstReg)
6298 .addReg(OpDstReg);
6299 }
6300 } else {
6301 Register LaneValueLoReg =
6302 MRI.createVirtualRegister(&AMDGPU::SReg_32_XM0RegClass);
6303 Register LaneValueHiReg =
6304 MRI.createVirtualRegister(&AMDGPU::SReg_32_XM0RegClass);
6305 Register LaneValReg =
6306 MRI.createVirtualRegister(&AMDGPU::SReg_64RegClass);
6307 auto [Op1L, Op1H] = ExtractSubRegs(MI, MI.getOperand(1),
6308 MRI.getRegClass(SrcReg), ST, MRI);
6309 // lane value input should be in an sgpr
6310 BuildMI(*ComputeLoop, I, DL, TII->get(AMDGPU::V_READLANE_B32),
6311 LaneValueLoReg)
6312 .addReg(Op1L)
6313 .addReg(FF1Reg);
6314 BuildMI(*ComputeLoop, I, DL, TII->get(AMDGPU::V_READLANE_B32),
6315 LaneValueHiReg)
6316 .addReg(Op1H)
6317 .addReg(FF1Reg);
6318 auto LaneValue = BuildRegSequence(*ComputeLoop, I, LaneValReg,
6319 LaneValueLoReg, LaneValueHiReg);
6320 switch (Opc) {
6321 case AMDGPU::S_OR_B64:
6322 case AMDGPU::S_AND_B64:
6323 case AMDGPU::S_XOR_B64: {
6324 NewAccumulator = BuildMI(*ComputeLoop, I, DL, TII->get(Opc), DstReg)
6325 .addReg(Accumulator->getOperand(0).getReg())
6326 .addReg(LaneValue->getOperand(0).getReg())
6327 .setOperandDead(3); // Dead scc
6328 break;
6329 }
6330 case AMDGPU::V_CMP_GT_I64_e64:
6331 case AMDGPU::V_CMP_GT_U64_e64:
6332 case AMDGPU::V_CMP_LT_I64_e64:
6333 case AMDGPU::V_CMP_LT_U64_e64: {
6334 Register LaneMaskReg = MRI.createVirtualRegister(WaveMaskRegClass);
6335 Register ComparisonResultReg =
6336 MRI.createVirtualRegister(WaveMaskRegClass);
6337 int SrcIdx =
6338 AMDGPU::getNamedOperandIdx(MI.getOpcode(), AMDGPU::OpName::src);
6339 const TargetRegisterClass *VregClass =
6340 TRI->getAllocatableClass(TII->getRegClass(MI.getDesc(), SrcIdx));
6341 Register AccumulatorVReg = MRI.createVirtualRegister(VregClass);
6342 auto [SrcReg0Sub0, SrcReg0Sub1] = ExtractSubRegs(
6343 MI, Accumulator->getOperand(0), VregClass, ST, MRI);
6344 BuildRegSequence(*ComputeLoop, I, AccumulatorVReg, SrcReg0Sub0,
6345 SrcReg0Sub1);
6346 BuildMI(*ComputeLoop, I, DL, TII->get(Opc), LaneMaskReg)
6347 .addReg(LaneValue->getOperand(0).getReg())
6348 .addReg(AccumulatorVReg);
6349
6350 unsigned AndOpc = IsWave32 ? AMDGPU::S_AND_B32 : AMDGPU::S_AND_B64;
6351 BuildMI(*ComputeLoop, I, DL, TII->get(AndOpc), ComparisonResultReg)
6352 .addReg(LaneMaskReg)
6353 .addReg(ActiveBitsReg);
6354
6355 NewAccumulator = BuildMI(*ComputeLoop, I, DL,
6356 TII->get(AMDGPU::S_CSELECT_B64), DstReg)
6357 .addReg(LaneValue->getOperand(0).getReg())
6358 .addReg(Accumulator->getOperand(0).getReg());
6359 break;
6360 }
6361 case AMDGPU::V_MIN_F64_e64:
6362 case AMDGPU::V_MIN_NUM_F64_e64:
6363 case AMDGPU::V_MAX_F64_e64:
6364 case AMDGPU::V_MAX_NUM_F64_e64:
6365 case AMDGPU::V_ADD_F64_e64:
6366 case AMDGPU::V_ADD_F64_pseudo_e64: {
6367 int SrcIdx =
6368 AMDGPU::getNamedOperandIdx(MI.getOpcode(), AMDGPU::OpName::src);
6369 const TargetRegisterClass *VregRC =
6370 TRI->getAllocatableClass(TII->getRegClass(MI.getDesc(), SrcIdx));
6371 Register AccumulatorVReg = MRI.createVirtualRegister(VregRC);
6372 Register DstVreg = MRI.createVirtualRegister(VregRC);
6373 Register LaneValLo =
6374 MRI.createVirtualRegister(&AMDGPU::SReg_32_XM0RegClass);
6375 Register LaneValHi =
6376 MRI.createVirtualRegister(&AMDGPU::SReg_32_XM0RegClass);
6377 BuildMI(*ComputeLoop, I, DL, TII->get(AMDGPU::COPY), AccumulatorVReg)
6378 .addReg(Accumulator->getOperand(0).getReg());
6379 unsigned Modifier =
6380 MI.getOpcode() == AMDGPU::WAVE_REDUCE_FSUB_PSEUDO_F64
6383 auto DstVregInst =
6384 BuildMI(*ComputeLoop, I, DL, TII->get(Opc), DstVreg)
6385 .addImm(Modifier) // src0 modifiers
6386 .addReg(LaneValue->getOperand(0).getReg())
6387 .addImm(SISrcMods::NONE) // src1 modifiers
6388 .addReg(AccumulatorVReg)
6389 .addImm(SISrcMods::NONE) // clamp
6390 .addImm(SISrcMods::NONE); // omod
6391 auto ReadLaneLo =
6392 BuildMI(*ComputeLoop, I, DL,
6393 TII->get(AMDGPU::V_READFIRSTLANE_B32), LaneValLo);
6394 auto ReadLaneHi =
6395 BuildMI(*ComputeLoop, I, DL,
6396 TII->get(AMDGPU::V_READFIRSTLANE_B32), LaneValHi);
6397 MachineBasicBlock::iterator Iters = *ReadLaneLo;
6398 auto [Op1L, Op1H] = ExtractSubRegs(*Iters, DstVregInst->getOperand(0),
6399 VregRC, ST, MRI);
6400 ReadLaneLo.addReg(Op1L);
6401 ReadLaneHi.addReg(Op1H);
6402 NewAccumulator =
6403 BuildRegSequence(*ComputeLoop, I, DstReg, LaneValLo, LaneValHi);
6404 break;
6405 }
6406 case AMDGPU::S_ADD_U64_PSEUDO:
6407 case AMDGPU::S_SUB_U64_PSEUDO: {
6408 NewAccumulator = BuildMI(*ComputeLoop, I, DL, TII->get(Opc), DstReg)
6409 .addReg(Accumulator->getOperand(0).getReg())
6410 .addReg(LaneValue->getOperand(0).getReg());
6411 ComputeLoop =
6412 expand64BitScalarArithmetic(*NewAccumulator, ComputeLoop);
6413 break;
6414 }
6415 }
6416 }
6417 // Manipulate the iterator to get the next active lane
6418 unsigned BITSETOpc =
6419 IsWave32 ? AMDGPU::S_BITSET0_B32 : AMDGPU::S_BITSET0_B64;
6420 BuildMI(*ComputeLoop, I, DL, TII->get(BITSETOpc), NewActiveBitsReg)
6421 .addReg(FF1Reg)
6422 .addReg(ActiveBitsReg);
6423
6424 // Add phi nodes
6425 Accumulator.addReg(DstReg).addMBB(ComputeLoop);
6426 ActiveBits.addReg(NewActiveBitsReg).addMBB(ComputeLoop);
6427
6428 // Creating branching
6429 MachineInstrBuilder SetSCCInstr;
6430 if (!ST.hasScalarCompareEq64()) {
6431 // For targets <= gfx7, use an S_OR_B32/B64 instruction to set SCC.
6432 Register LaneMaskReg = MRI.createVirtualRegister(WaveMaskRegClass);
6433 unsigned CMPOpc = IsWave32 ? AMDGPU::S_OR_B32 : AMDGPU::S_OR_B64;
6434 SetSCCInstr =
6435 BuildMI(*ComputeLoop, I, DL, TII->get(CMPOpc), LaneMaskReg);
6436 } else {
6437 unsigned CMPOpc =
6438 IsWave32 ? AMDGPU::S_CMP_LG_U32 : AMDGPU::S_CMP_LG_U64;
6439 SetSCCInstr = BuildMI(*ComputeLoop, I, DL, TII->get(CMPOpc));
6440 }
6441 SetSCCInstr.addReg(NewActiveBitsReg);
6442 if (ST.hasScalarCompareEq64())
6443 SetSCCInstr.addImm(0);
6444 else
6445 SetSCCInstr.addReg(NewActiveBitsReg);
6446 BuildMI(*ComputeLoop, I, DL, TII->get(AMDGPU::S_CBRANCH_SCC1))
6447 .addMBB(ComputeLoop);
6448
6449 RetBB = ComputeEnd;
6450 } else {
6451 assert(ST.hasDPP() && "Sub Target does not support DPP Operations");
6452 MachineBasicBlock *CurrBB = &BB;
6453 Register SrcWithIdentity = MRI.createVirtualRegister(SrcRegClass);
6454 Register IdentityVGPR = MRI.createVirtualRegister(SrcRegClass);
6455 Register IdentitySGPR = MRI.createVirtualRegister(DstRegClass);
6456 Register DPPRowShr1 = MRI.createVirtualRegister(SrcRegClass);
6457 Register DPPRowShr2 = MRI.createVirtualRegister(SrcRegClass);
6458 Register DPPRowShr4 = MRI.createVirtualRegister(SrcRegClass);
6459 Register DPPRowShr8 = MRI.createVirtualRegister(SrcRegClass);
6460 Register RowBcast15 = MRI.createVirtualRegister(SrcRegClass);
6461 Register ReducedValSGPR = MRI.createVirtualRegister(DstRegClass);
6462 Register NegatedReducedVal = MRI.createVirtualRegister(DstRegClass);
6463 Register RowBcast31 = MRI.createVirtualRegister(SrcRegClass);
6464 Register UndefExec = MRI.createVirtualRegister(WaveMaskRegClass);
6465 Register FinalDPPResult;
6466 MachineInstr *SrcWithIdentityInstr;
6467 MachineInstr *LastBcastInstr;
6468 BuildMI(*CurrBB, MI, DL, TII->get(AMDGPU::IMPLICIT_DEF), UndefExec);
6469
6471 BuildMI(*CurrBB, MI, DL,
6472 TII->get(is32BitOpc ? AMDGPU::S_MOV_B32
6473 : AMDGPU::S_MOV_B64_IMM_PSEUDO),
6474 IdentitySGPR)
6475 .addImm(IdentityValue);
6476 auto IdentityCopyInstr =
6477 BuildMI(*CurrBB, MI, DL, TII->get(AMDGPU::COPY), IdentityVGPR)
6478 .addReg(IdentitySGPR);
6479 auto DPPClampOpcPair = getDPPOpcForWaveReduction(Opc, ST);
6480 unsigned DPPOpc = std::get<0>(DPPClampOpcPair);
6481 unsigned ClampOpc = std::get<1>(DPPClampOpcPair);
6482 auto BuildSetInactiveInstr = [&](Register Dst, Register Src0,
6483 Register Src1) {
6484 return BuildMI(BB, MI, DL, TII->get(AMDGPU::V_SET_INACTIVE_B32),
6485 Dst)
6486 .addImm(0) // src0 modifiers
6487 .addReg(Src0) // src0
6488 .addImm(0) // src1 modifiers
6489 .addReg(Src1) // identity value for inactive lanes
6490 .addReg(UndefExec); // bool i1
6491 };
6492 auto BuildDPPMachineInstr = [&](Register Dst, Register Src,
6493 unsigned DPPCtrl) {
6494 auto DPPInstr =
6495 BuildMI(*CurrBB, MI, DL, TII->get(DPPOpc), Dst).addReg(Src); // old
6496 if (isFPOp && !NeedsMovDPP)
6497 DPPInstr.addImm(SISrcMods::NONE); // src0 modifier
6498 DPPInstr.addReg(Src); // src0
6499 if (isFPOp && !NeedsMovDPP)
6500 DPPInstr.addImm(SISrcMods::NONE); // src1 modifier
6501 if (!NeedsMovDPP)
6502 DPPInstr.addReg(Src); // src1
6503 if (AMDGPU::getNamedOperandIdx(DPPOpc, AMDGPU::OpName::clamp) >= 0)
6504 DPPInstr.addImm(0); // clamp
6505 DPPInstr
6506 .addImm(DPPCtrl) // dpp-ctrl
6507 .addImm(0xf) // row-mask
6508 .addImm(0xf) // bank-mask
6509 .addImm(0); // bound-control
6510 };
6511 auto BuildClampInstr = [&](Register Dst, Register Src0, Register Src1,
6512 bool isAddSub = false,
6513 bool needsCarryIn = false,
6514 Register CarryIn = Register()) {
6515 unsigned InstrOpc = ClampOpc;
6516 Register CarryOutReg = MRI.createVirtualRegister(WaveMaskRegClass);
6517 if (needsCarryIn)
6518 InstrOpc = AMDGPU::V_ADDC_U32_e64;
6519 auto ClampInstr = BuildMI(*CurrBB, MI, DL, TII->get(InstrOpc), Dst);
6520 if (isFPOp)
6521 ClampInstr.addImm(SISrcMods::NONE); // src0 mod
6522 if (isAddSub) {
6523 if (needsCarryIn)
6524 ClampInstr.addReg(CarryOutReg,
6526 RegState::Dead); // killed carry-out reg
6527 else
6528 ClampInstr.addReg(CarryOutReg, RegState::Define); // carry-out reg
6529 }
6530 ClampInstr.addReg(Src0); // src0
6531 if (isFPOp)
6532 ClampInstr.addImm(SISrcMods::NONE); // src1 mod
6533 ClampInstr.addReg(Src1); // src1
6534 if (needsCarryIn)
6535 ClampInstr.addReg(CarryIn, RegState::Kill); // carry-in reg
6536 if (AMDGPU::getNamedOperandIdx(InstrOpc, AMDGPU::OpName::clamp) >= 0)
6537 ClampInstr.addImm(0); // clamp
6538 if (isFPOp)
6539 ClampInstr.addImm(0); // omod
6540 LastBcastInstr = ClampInstr;
6541 return CarryOutReg;
6542 };
6543 auto BuildPostDPPInstr = [&](Register Src0, Register Src1) {
6544 bool isAddSubOpc =
6545 Opc == AMDGPU::S_ADD_U64_PSEUDO || Opc == AMDGPU::S_SUB_U64_PSEUDO;
6546 bool isBitWiseOpc = Opc == AMDGPU::S_AND_B64 ||
6547 Opc == AMDGPU::S_OR_B64 || Opc == AMDGPU::S_XOR_B64;
6548 Register ReturnReg = MRI.createVirtualRegister(SrcRegClass);
6549 if (isAddSubOpc || isBitWiseOpc) {
6550 Register ResLo = MRI.createVirtualRegister(&AMDGPU::VGPR_32RegClass);
6551 Register ResHi = MRI.createVirtualRegister(&AMDGPU::VGPR_32RegClass);
6552 MachineOperand Src0Operand =
6553 MachineOperand::CreateReg(Src0, /*isDef=*/false);
6554 MachineOperand Src1Operand =
6555 MachineOperand::CreateReg(Src1, /*isDef=*/false);
6556 auto [Src0Lo, Src0Hi] =
6557 ExtractSubRegs(MI, Src0Operand, SrcRegClass, ST, MRI);
6558 auto [Src1Lo, Src1Hi] =
6559 ExtractSubRegs(MI, Src1Operand, SrcRegClass, ST, MRI);
6560 Register CarryReg = BuildClampInstr(
6561 ResLo, Src0Lo, Src1Lo, isAddSubOpc, /*needsCarryIn*/ false);
6562 BuildClampInstr(ResHi, Src0Hi, Src1Hi, isAddSubOpc,
6563 /*needsCarryIn*/ isAddSubOpc, CarryReg);
6564 BuildRegSequence(*CurrBB, MI, ReturnReg, ResLo, ResHi);
6565 } else {
6566 if (isFPOp) {
6567 BuildMI(*CurrBB, MI, DL, TII->get(Opc), ReturnReg)
6568 .addImm(SISrcMods::NONE) // src0 modifiers
6569 .addReg(Src0)
6570 .addImm(SISrcMods::NONE) // src1 modifiers
6571 .addReg(Src1)
6572 .addImm(SISrcMods::NONE) // clamp
6573 .addImm(SISrcMods::NONE); // omod
6574 } else {
6575 Register CmpMaskReg = MRI.createVirtualRegister(WaveMaskRegClass);
6576 BuildMI(*CurrBB, MI, DL, TII->get(Opc), CmpMaskReg)
6577 .addReg(Src0) // src0
6578 .addReg(Src1); // src1
6579 LastBcastInstr =
6580 BuildMI(*CurrBB, MI, DL, TII->get(AMDGPU::V_CNDMASK_B64_PSEUDO),
6581 ReturnReg)
6582 .addReg(Src1) // src0
6583 .addReg(Src0) // src1
6584 .addReg(CmpMaskReg); // src2
6585 expand64BitV_CNDMASK(*LastBcastInstr, CurrBB);
6586 }
6587 }
6588 return ReturnReg;
6589 };
6590
6591 // Set inactive lanes to the identity value.
6592 if (is32BitOpc) {
6593 SrcWithIdentityInstr =
6594 BuildSetInactiveInstr(SrcWithIdentity, SrcReg, IdentityVGPR);
6595 } else {
6596 Register SrcWithIdentitylo =
6597 MRI.createVirtualRegister(&AMDGPU::VGPR_32RegClass);
6598 Register SrcWithIdentityhi =
6599 MRI.createVirtualRegister(&AMDGPU::VGPR_32RegClass);
6600 auto [Reg0Sub0, Reg0Sub1] = ExtractSubRegs(
6601 MI, IdentityCopyInstr->getOperand(0), SrcRegClass, ST, MRI);
6602 auto [SrcReg0Sub0, SrcReg0Sub1] =
6603 ExtractSubRegs(MI, MI.getOperand(1), SrcRegClass, ST, MRI);
6604 MachineInstr *SetInactiveLoInstr =
6605 BuildSetInactiveInstr(SrcWithIdentitylo, SrcReg0Sub0, Reg0Sub0);
6606 MachineInstr *SetInactiveHiInstr =
6607 BuildSetInactiveInstr(SrcWithIdentityhi, SrcReg0Sub1, Reg0Sub1);
6608 SrcWithIdentityInstr =
6609 BuildRegSequence(*CurrBB, MI, SrcWithIdentity,
6610 SetInactiveLoInstr->getOperand(0).getReg(),
6611 SetInactiveHiInstr->getOperand(0).getReg());
6612 }
6613 // DPP reduction
6614 Register SrcWithIdentityReg =
6615 SrcWithIdentityInstr->getOperand(0).getReg();
6616 BuildDPPMachineInstr(DPPRowShr1, SrcWithIdentityReg,
6618 if (NeedsMovDPP)
6619 DPPRowShr1 = BuildPostDPPInstr(SrcWithIdentityReg, DPPRowShr1);
6620
6621 BuildDPPMachineInstr(DPPRowShr2, DPPRowShr1,
6623 if (NeedsMovDPP)
6624 DPPRowShr2 = BuildPostDPPInstr(DPPRowShr1, DPPRowShr2);
6625
6626 BuildDPPMachineInstr(DPPRowShr4, DPPRowShr2,
6628 if (NeedsMovDPP)
6629 DPPRowShr4 = BuildPostDPPInstr(DPPRowShr2, DPPRowShr4);
6630
6631 BuildDPPMachineInstr(DPPRowShr8, DPPRowShr4,
6633 if (NeedsMovDPP)
6634 DPPRowShr8 = BuildPostDPPInstr(DPPRowShr4, DPPRowShr8);
6635
6636 if (ST.hasDPPBroadcasts()) {
6637 BuildDPPMachineInstr(RowBcast15, DPPRowShr8, AMDGPU::DPP::BCAST15);
6638 if (NeedsMovDPP)
6639 RowBcast15 = BuildPostDPPInstr(DPPRowShr8, RowBcast15);
6640 } else {
6641 // magic constant: 0x1E0
6642 // To Set BIT_MODE : bit 15 = 0
6643 // XOR mask : bit [14:10] = 0
6644 // OR mask : bit [9:5] = 15
6645 // AND mask : bit [4:0] = 0
6646 if (is32BitOpc) {
6647 Register SwizzledValue =
6648 MRI.createVirtualRegister(&AMDGPU::VGPR_32RegClass);
6649 BuildMI(*CurrBB, MI, DL, TII->get(AMDGPU::DS_SWIZZLE_B32),
6650 SwizzledValue)
6651 .addReg(DPPRowShr8) // addr
6652 .addImm(0x1E0) // swizzle offset (i16)
6653 .addImm(0x0); // gds (i1)
6654 BuildClampInstr(RowBcast15, DPPRowShr8, SwizzledValue);
6655 } else {
6656 Register SwizzledValuelo =
6657 MRI.createVirtualRegister(&AMDGPU::VGPR_32RegClass);
6658 Register SwizzledValuehi =
6659 MRI.createVirtualRegister(&AMDGPU::VGPR_32RegClass);
6660 Register SwizzledValue64 = MRI.createVirtualRegister(SrcRegClass);
6661 MachineOperand DPPRowShr8Op =
6662 MachineOperand::CreateReg(DPPRowShr8, /*isDef=*/false);
6663 auto [Op1L, Op1H] =
6664 ExtractSubRegs(MI, DPPRowShr8Op, SrcRegClass, ST, MRI);
6665 BuildMI(*CurrBB, MI, DL, TII->get(AMDGPU::DS_SWIZZLE_B32),
6666 SwizzledValuelo)
6667 .addReg(Op1L) // addr
6668 .addImm(0x1E0) // swizzle offset (i16)
6669 .addImm(0x0); // gds (i1)
6670 BuildMI(*CurrBB, MI, DL, TII->get(AMDGPU::DS_SWIZZLE_B32),
6671 SwizzledValuehi)
6672 .addReg(Op1H) // addr
6673 .addImm(0x1E0) // swizzle offset (i16)
6674 .addImm(0x0); // gds (i1)
6675 BuildRegSequence(*CurrBB, MI, SwizzledValue64, SwizzledValuelo,
6676 SwizzledValuehi);
6677 if (NeedsMovDPP)
6678 RowBcast15 = BuildPostDPPInstr(DPPRowShr8, SwizzledValue64);
6679 else
6680 BuildClampInstr(RowBcast15, DPPRowShr8, SwizzledValue64);
6681 }
6682 }
6683 FinalDPPResult = RowBcast15;
6684 if (!IsWave32) {
6685 if (ST.hasDPPBroadcasts()) {
6686 BuildDPPMachineInstr(RowBcast31, RowBcast15, AMDGPU::DPP::BCAST31);
6687 if (NeedsMovDPP)
6688 RowBcast31 = BuildPostDPPInstr(RowBcast15, RowBcast31);
6689 } else {
6690 Register ShiftedThreadID =
6691 MRI.createVirtualRegister(&AMDGPU::VGPR_32RegClass);
6692 Register PermuteByteOffset =
6693 MRI.createVirtualRegister(&AMDGPU::VGPR_32RegClass);
6694 Register PermutedValue = MRI.createVirtualRegister(SrcRegClass);
6695 Register Lane32Offset =
6696 MRI.createVirtualRegister(&AMDGPU::SReg_32RegClass);
6697 Register WordSizeConst =
6698 MRI.createVirtualRegister(&AMDGPU::SReg_32RegClass);
6699 Register ThreadIDRegLo =
6700 MRI.createVirtualRegister(&AMDGPU::VGPR_32RegClass);
6701 Register ThreadIDReg =
6702 MRI.createVirtualRegister(&AMDGPU::VGPR_32RegClass);
6703 // Get the thread ID.
6704 BuildMI(*CurrBB, MI, DL, TII->get(AMDGPU::V_MBCNT_LO_U32_B32_e64),
6705 ThreadIDRegLo)
6706 .addImm(-1)
6707 .addImm(0);
6708 BuildMI(*CurrBB, MI, DL, TII->get(AMDGPU::V_MBCNT_HI_U32_B32_e64),
6709 ThreadIDReg)
6710 .addImm(-1)
6711 .addReg(ThreadIDRegLo);
6712 // shift each lane over by 32 positions, so value in 31st lane is
6713 // present in 63rd lane.
6714 BuildMI(*CurrBB, MI, DL, TII->get(AMDGPU::S_MOV_B32), Lane32Offset)
6715 .addImm(0x20);
6716 BuildMI(*CurrBB, MI, DL, TII->get(AMDGPU::V_ADD_U32_e64),
6717 ShiftedThreadID)
6718 .addReg(ThreadIDReg)
6719 .addReg(Lane32Offset)
6720 .addImm(0); // clamp
6721 // multiply by reg size.
6722 BuildMI(*CurrBB, MI, DL, TII->get(AMDGPU::S_MOV_B32), WordSizeConst)
6723 .addImm(0x4);
6724 BuildMI(*CurrBB, MI, DL, TII->get(AMDGPU::V_MUL_LO_U32_e64),
6725 PermuteByteOffset)
6726 .addReg(WordSizeConst)
6727 .addReg(ShiftedThreadID);
6728 // Permute the lanes
6729 if (is32BitOpc) {
6730 BuildMI(*CurrBB, MI, DL, TII->get(AMDGPU::DS_PERMUTE_B32),
6731 PermutedValue)
6732 .addReg(PermuteByteOffset) // addr
6733 .addReg(RowBcast15) // data
6734 .addImm(0); // offset
6735 } else {
6736 Register PermutedValuelo =
6737 MRI.createVirtualRegister(&AMDGPU::VGPR_32RegClass);
6738 Register PermutedValuehi =
6739 MRI.createVirtualRegister(&AMDGPU::VGPR_32RegClass);
6740 MachineOperand RowBcast15Op =
6741 MachineOperand::CreateReg(RowBcast15, /*isDef=*/false);
6742 auto [RowBcast15Lo, RowBcast15Hi] =
6743 ExtractSubRegs(MI, RowBcast15Op, SrcRegClass, ST, MRI);
6744 BuildMI(*CurrBB, MI, DL, TII->get(AMDGPU::DS_PERMUTE_B32),
6745 PermutedValuelo)
6746 .addReg(PermuteByteOffset) // addr
6747 .addReg(RowBcast15Lo) // swizzle offset (i16)
6748 .addImm(0x0); // gds (i1)
6749 BuildMI(*CurrBB, MI, DL, TII->get(AMDGPU::DS_PERMUTE_B32),
6750 PermutedValuehi)
6751 .addReg(PermuteByteOffset) // addr
6752 .addReg(RowBcast15Hi) // swizzle offset (i16)
6753 .addImm(0x0); // gds (i1)
6754 BuildRegSequence(*CurrBB, MI, PermutedValue, PermutedValuelo,
6755 PermutedValuehi);
6756 }
6757 if (NeedsMovDPP)
6758 RowBcast31 = BuildPostDPPInstr(RowBcast15, PermutedValue);
6759 else
6760 BuildClampInstr(RowBcast31, RowBcast15, PermutedValue);
6761 }
6762 FinalDPPResult = RowBcast31;
6763 }
6764 if (MIOpc == AMDGPU::WAVE_REDUCE_FSUB_PSEUDO_F32 ||
6765 MIOpc == AMDGPU::WAVE_REDUCE_FSUB_PSEUDO_F64) {
6766 Register NegatedValVGPR = MRI.createVirtualRegister(SrcRegClass);
6767 // Opc for f32 reduction is V_SUB_F32.
6768 // For f64, there is no equivalent V_SUB_F64 opcode, so use
6769 // V_ADD_F64/V_ADD_F64_pseudo, and negate the second operand.
6770 BuildMI(*CurrBB, MI, DL, TII->get(Opc),
6771 NegatedValVGPR)
6772 .addImm(SISrcMods::NONE) // src0 mods
6773 .addReg(IdentityVGPR) // src0
6774 .addImm(is32BitOpc ? SISrcMods::NONE : SISrcMods::NEG) // src1 mods
6775 .addReg(IsWave32 ? RowBcast15 : RowBcast31) // src1
6776 .addImm(SISrcMods::NONE) // clamp
6777 .addImm(SISrcMods::NONE); // omod
6778 FinalDPPResult = NegatedValVGPR;
6779 }
6780 // The final reduced value is in the last lane.
6781 if (is32BitOpc) {
6782 BuildMI(*CurrBB, MI, DL, TII->get(AMDGPU::V_READLANE_B32),
6783 ReducedValSGPR)
6784 .addReg(FinalDPPResult)
6785 .addImm(ST.getWavefrontSize() - 1);
6786 } else {
6787 Register LaneValueLoReg =
6788 MRI.createVirtualRegister(&AMDGPU::SReg_32_XM0RegClass);
6789 Register LaneValueHiReg =
6790 MRI.createVirtualRegister(&AMDGPU::SReg_32_XM0RegClass);
6791 const TargetRegisterClass *SrcRC = MRI.getRegClass(SrcReg);
6792 MachineOperand FinalDPPResultOperand =
6793 MachineOperand::CreateReg(FinalDPPResult, /*isDef=*/false);
6794 auto [Op1L, Op1H] =
6795 ExtractSubRegs(MI, FinalDPPResultOperand, SrcRC, ST, MRI);
6796 // lane value input should be in an sgpr
6797 BuildMI(*CurrBB, MI, DL, TII->get(AMDGPU::V_READLANE_B32),
6798 LaneValueLoReg)
6799 .addReg(Op1L)
6800 .addImm(ST.getWavefrontSize() - 1);
6801 BuildMI(*CurrBB, MI, DL, TII->get(AMDGPU::V_READLANE_B32),
6802 LaneValueHiReg)
6803 .addReg(Op1H)
6804 .addImm(ST.getWavefrontSize() - 1);
6805 BuildRegSequence(*CurrBB, MI, ReducedValSGPR, LaneValueLoReg,
6806 LaneValueHiReg);
6807 }
6808 if (Opc == AMDGPU::S_SUB_I32) {
6809 BuildMI(*CurrBB, MI, DL, TII->get(AMDGPU::S_SUB_I32), NegatedReducedVal)
6810 .addImm(0)
6811 .addReg(ReducedValSGPR);
6812 } else if (Opc == AMDGPU::S_SUB_U64_PSEUDO) {
6813 auto NegatedValInstr =
6814 BuildMI(*CurrBB, MI, DL, TII->get(Opc), NegatedReducedVal)
6815 .addImm(0)
6816 .addReg(ReducedValSGPR);
6817 CurrBB = expand64BitScalarArithmetic(*NegatedValInstr, CurrBB);
6818 }
6819 // Mark the final result as a whole-wave-mode calculation.
6820 BuildMI(*CurrBB, MI, DL, TII->get(AMDGPU::STRICT_WWM), DstReg)
6821 .addReg(Opc == AMDGPU::S_SUB_I32 || Opc == AMDGPU::S_SUB_U64_PSEUDO
6822 ? NegatedReducedVal
6823 : ReducedValSGPR);
6824 RetBB = CurrBB;
6825 }
6826 }
6827 MI.eraseFromParent();
6828 return RetBB;
6829}
6830
6833 MachineBasicBlock *BB) const {
6834 MachineFunction *MF = BB->getParent();
6836 const GCNSubtarget &ST = MF->getSubtarget<GCNSubtarget>();
6838 const SIRegisterInfo *TRI = Subtarget->getRegisterInfo();
6839 MachineRegisterInfo &MRI = MF->getRegInfo();
6840 const DebugLoc &DL = MI.getDebugLoc();
6841
6842 switch (MI.getOpcode()) {
6843 case AMDGPU::WAVE_REDUCE_UMIN_PSEUDO_U32:
6844 return lowerWaveReduce(MI, *BB, *getSubtarget(), AMDGPU::S_MIN_U32);
6845 case AMDGPU::WAVE_REDUCE_UMIN_PSEUDO_U64:
6846 return lowerWaveReduce(MI, *BB, *getSubtarget(), AMDGPU::V_CMP_LT_U64_e64);
6847 case AMDGPU::WAVE_REDUCE_MIN_PSEUDO_I32:
6848 return lowerWaveReduce(MI, *BB, *getSubtarget(), AMDGPU::S_MIN_I32);
6849 case AMDGPU::WAVE_REDUCE_MIN_PSEUDO_I64:
6850 return lowerWaveReduce(MI, *BB, *getSubtarget(), AMDGPU::V_CMP_LT_I64_e64);
6851 case AMDGPU::WAVE_REDUCE_FMIN_PSEUDO_F32:
6852 return lowerWaveReduce(MI, *BB, *getSubtarget(), AMDGPU::V_MIN_F32_e64);
6853 case AMDGPU::WAVE_REDUCE_FMIN_PSEUDO_F64:
6854 return lowerWaveReduce(MI, *BB, *getSubtarget(),
6855 ST.getGeneration() >= AMDGPUSubtarget::GFX12
6856 ? AMDGPU::V_MIN_NUM_F64_e64
6857 : AMDGPU::V_MIN_F64_e64);
6858 case AMDGPU::WAVE_REDUCE_UMAX_PSEUDO_U32:
6859 return lowerWaveReduce(MI, *BB, *getSubtarget(), AMDGPU::S_MAX_U32);
6860 case AMDGPU::WAVE_REDUCE_UMAX_PSEUDO_U64:
6861 return lowerWaveReduce(MI, *BB, *getSubtarget(), AMDGPU::V_CMP_GT_U64_e64);
6862 case AMDGPU::WAVE_REDUCE_MAX_PSEUDO_I32:
6863 return lowerWaveReduce(MI, *BB, *getSubtarget(), AMDGPU::S_MAX_I32);
6864 case AMDGPU::WAVE_REDUCE_MAX_PSEUDO_I64:
6865 return lowerWaveReduce(MI, *BB, *getSubtarget(), AMDGPU::V_CMP_GT_I64_e64);
6866 case AMDGPU::WAVE_REDUCE_FMAX_PSEUDO_F32:
6867 return lowerWaveReduce(MI, *BB, *getSubtarget(), AMDGPU::V_MAX_F32_e64);
6868 case AMDGPU::WAVE_REDUCE_FMAX_PSEUDO_F64:
6869 return lowerWaveReduce(MI, *BB, *getSubtarget(),
6870 ST.getGeneration() >= AMDGPUSubtarget::GFX12
6871 ? AMDGPU::V_MAX_NUM_F64_e64
6872 : AMDGPU::V_MAX_F64_e64);
6873 case AMDGPU::WAVE_REDUCE_ADD_PSEUDO_I32:
6874 return lowerWaveReduce(MI, *BB, *getSubtarget(), AMDGPU::S_ADD_I32);
6875 case AMDGPU::WAVE_REDUCE_ADD_PSEUDO_U64:
6876 return lowerWaveReduce(MI, *BB, *getSubtarget(), AMDGPU::S_ADD_U64_PSEUDO);
6877 case AMDGPU::WAVE_REDUCE_FADD_PSEUDO_F32:
6878 return lowerWaveReduce(MI, *BB, *getSubtarget(), AMDGPU::V_ADD_F32_e64);
6879 case AMDGPU::WAVE_REDUCE_FADD_PSEUDO_F64:
6880 return lowerWaveReduce(MI, *BB, *getSubtarget(),
6881 ST.getGeneration() >= AMDGPUSubtarget::GFX12
6882 ? AMDGPU::V_ADD_F64_pseudo_e64
6883 : AMDGPU::V_ADD_F64_e64);
6884 case AMDGPU::WAVE_REDUCE_SUB_PSEUDO_I32:
6885 return lowerWaveReduce(MI, *BB, *getSubtarget(), AMDGPU::S_SUB_I32);
6886 case AMDGPU::WAVE_REDUCE_SUB_PSEUDO_U64:
6887 return lowerWaveReduce(MI, *BB, *getSubtarget(), AMDGPU::S_SUB_U64_PSEUDO);
6888 case AMDGPU::WAVE_REDUCE_FSUB_PSEUDO_F32:
6889 return lowerWaveReduce(MI, *BB, *getSubtarget(), AMDGPU::V_SUB_F32_e64);
6890 case AMDGPU::WAVE_REDUCE_FSUB_PSEUDO_F64:
6891 // There is no S/V_SUB_F64 opcode. Double type subtraction is expanded as
6892 // fadd + neg, by setting the NEG bit in the instruction.
6893 return lowerWaveReduce(MI, *BB, *getSubtarget(),
6894 ST.getGeneration() >= AMDGPUSubtarget::GFX12
6895 ? AMDGPU::V_ADD_F64_pseudo_e64
6896 : AMDGPU::V_ADD_F64_e64);
6897 case AMDGPU::WAVE_REDUCE_AND_PSEUDO_B32:
6898 return lowerWaveReduce(MI, *BB, *getSubtarget(), AMDGPU::S_AND_B32);
6899 case AMDGPU::WAVE_REDUCE_AND_PSEUDO_B64:
6900 return lowerWaveReduce(MI, *BB, *getSubtarget(), AMDGPU::S_AND_B64);
6901 case AMDGPU::WAVE_REDUCE_OR_PSEUDO_B32:
6902 return lowerWaveReduce(MI, *BB, *getSubtarget(), AMDGPU::S_OR_B32);
6903 case AMDGPU::WAVE_REDUCE_OR_PSEUDO_B64:
6904 return lowerWaveReduce(MI, *BB, *getSubtarget(), AMDGPU::S_OR_B64);
6905 case AMDGPU::WAVE_REDUCE_XOR_PSEUDO_B32:
6906 return lowerWaveReduce(MI, *BB, *getSubtarget(), AMDGPU::S_XOR_B32);
6907 case AMDGPU::WAVE_REDUCE_XOR_PSEUDO_B64:
6908 return lowerWaveReduce(MI, *BB, *getSubtarget(), AMDGPU::S_XOR_B64);
6909 case AMDGPU::S_UADDO_PSEUDO:
6910 case AMDGPU::S_USUBO_PSEUDO: {
6911 MachineOperand &Dest0 = MI.getOperand(0);
6912 MachineOperand &Dest1 = MI.getOperand(1);
6913 MachineOperand &Src0 = MI.getOperand(2);
6914 MachineOperand &Src1 = MI.getOperand(3);
6915
6916 unsigned Opc = (MI.getOpcode() == AMDGPU::S_UADDO_PSEUDO)
6917 ? AMDGPU::S_ADD_U32
6918 : AMDGPU::S_SUB_U32;
6919 // clang-format off
6920 BuildMI(*BB, MI, DL, TII->get(Opc), Dest0.getReg())
6921 .add(Src0)
6922 .add(Src1);
6923 // clang-format on
6924
6925 unsigned SelOpc =
6926 Subtarget->isWave64() ? AMDGPU::S_CSELECT_B64 : AMDGPU::S_CSELECT_B32;
6927 BuildMI(*BB, MI, DL, TII->get(SelOpc), Dest1.getReg()).addImm(-1).addImm(0);
6928
6929 MI.eraseFromParent();
6930 return BB;
6931 }
6932 case AMDGPU::S_ADD_U64_PSEUDO:
6933 case AMDGPU::S_SUB_U64_PSEUDO: {
6934 return expand64BitScalarArithmetic(MI, BB);
6935 }
6936 case AMDGPU::V_ADD_U64_PSEUDO:
6937 case AMDGPU::V_SUB_U64_PSEUDO: {
6938 bool IsAdd = (MI.getOpcode() == AMDGPU::V_ADD_U64_PSEUDO);
6939
6940 MachineOperand &Dest = MI.getOperand(0);
6941 MachineOperand &Src0 = MI.getOperand(1);
6942 MachineOperand &Src1 = MI.getOperand(2);
6943
6944 if (ST.hasAddSubU64Insts()) {
6945 auto I = BuildMI(*BB, MI, DL,
6946 TII->get(IsAdd ? AMDGPU::V_ADD_U64_e64
6947 : AMDGPU::V_SUB_U64_e64),
6948 Dest.getReg())
6949 .add(Src0)
6950 .add(Src1)
6951 .addImm(0); // clamp
6952 TII->legalizeOperands(*I);
6953 MI.eraseFromParent();
6954 return BB;
6955 }
6956
6957 if (IsAdd && ST.hasLshlAddU64Inst()) {
6958 auto Add = BuildMI(*BB, MI, DL, TII->get(AMDGPU::V_LSHL_ADD_U64_e64),
6959 Dest.getReg())
6960 .add(Src0)
6961 .addImm(0)
6962 .add(Src1);
6963 TII->legalizeOperands(*Add);
6964 MI.eraseFromParent();
6965 return BB;
6966 }
6967
6968 const auto *CarryRC = TRI->getWaveMaskRegClass();
6969
6970 Register DestSub0 = MRI.createVirtualRegister(&AMDGPU::VGPR_32RegClass);
6971 Register DestSub1 = MRI.createVirtualRegister(&AMDGPU::VGPR_32RegClass);
6972
6973 Register CarryReg = MRI.createVirtualRegister(CarryRC);
6974 Register DeadCarryReg = MRI.createVirtualRegister(CarryRC);
6975
6976 const TargetRegisterClass *Src0RC = Src0.isReg()
6977 ? MRI.getRegClass(Src0.getReg())
6978 : &AMDGPU::VReg_64RegClass;
6979 const TargetRegisterClass *Src1RC = Src1.isReg()
6980 ? MRI.getRegClass(Src1.getReg())
6981 : &AMDGPU::VReg_64RegClass;
6982
6983 const TargetRegisterClass *Src0SubRC =
6984 TRI->getSubRegisterClass(Src0RC, AMDGPU::sub0);
6985 const TargetRegisterClass *Src1SubRC =
6986 TRI->getSubRegisterClass(Src1RC, AMDGPU::sub1);
6987
6988 MachineOperand SrcReg0Sub0 = TII->buildExtractSubRegOrImm(
6989 MI, MRI, Src0, Src0RC, AMDGPU::sub0, Src0SubRC);
6990 MachineOperand SrcReg1Sub0 = TII->buildExtractSubRegOrImm(
6991 MI, MRI, Src1, Src1RC, AMDGPU::sub0, Src1SubRC);
6992
6993 MachineOperand SrcReg0Sub1 = TII->buildExtractSubRegOrImm(
6994 MI, MRI, Src0, Src0RC, AMDGPU::sub1, Src0SubRC);
6995 MachineOperand SrcReg1Sub1 = TII->buildExtractSubRegOrImm(
6996 MI, MRI, Src1, Src1RC, AMDGPU::sub1, Src1SubRC);
6997
6998 unsigned LoOpc =
6999 IsAdd ? AMDGPU::V_ADD_CO_U32_e64 : AMDGPU::V_SUB_CO_U32_e64;
7000 MachineInstr *LoHalf = BuildMI(*BB, MI, DL, TII->get(LoOpc), DestSub0)
7001 .addReg(CarryReg, RegState::Define)
7002 .add(SrcReg0Sub0)
7003 .add(SrcReg1Sub0)
7004 .addImm(0); // clamp bit
7005
7006 unsigned HiOpc = IsAdd ? AMDGPU::V_ADDC_U32_e64 : AMDGPU::V_SUBB_U32_e64;
7007 MachineInstr *HiHalf =
7008 BuildMI(*BB, MI, DL, TII->get(HiOpc), DestSub1)
7009 .addReg(DeadCarryReg, RegState::Define | RegState::Dead)
7010 .add(SrcReg0Sub1)
7011 .add(SrcReg1Sub1)
7012 .addReg(CarryReg, RegState::Kill)
7013 .addImm(0); // clamp bit
7014
7015 BuildMI(*BB, MI, DL, TII->get(TargetOpcode::REG_SEQUENCE), Dest.getReg())
7016 .addReg(DestSub0)
7017 .addImm(AMDGPU::sub0)
7018 .addReg(DestSub1)
7019 .addImm(AMDGPU::sub1);
7020 TII->legalizeOperands(*LoHalf);
7021 TII->legalizeOperands(*HiHalf);
7022 MI.eraseFromParent();
7023 return BB;
7024 }
7025 case AMDGPU::S_ADD_CO_PSEUDO:
7026 case AMDGPU::S_SUB_CO_PSEUDO: {
7027 // This pseudo has a chance to be selected
7028 // only from uniform add/subcarry node. All the VGPR operands
7029 // therefore assumed to be splat vectors.
7031 MachineOperand &Dest = MI.getOperand(0);
7032 MachineOperand &CarryDest = MI.getOperand(1);
7033 MachineOperand &Src0 = MI.getOperand(2);
7034 MachineOperand &Src1 = MI.getOperand(3);
7035 MachineOperand &Src2 = MI.getOperand(4);
7036 if (Src0.isReg() && TRI->isVectorRegister(MRI, Src0.getReg())) {
7037 Register RegOp0 = MRI.createVirtualRegister(&AMDGPU::SReg_32_XM0RegClass);
7038 BuildMI(*BB, MII, DL, TII->get(AMDGPU::V_READFIRSTLANE_B32), RegOp0)
7039 .addReg(Src0.getReg());
7040 Src0.setReg(RegOp0);
7041 }
7042 if (Src1.isReg() && TRI->isVectorRegister(MRI, Src1.getReg())) {
7043 Register RegOp1 = MRI.createVirtualRegister(&AMDGPU::SReg_32_XM0RegClass);
7044 BuildMI(*BB, MII, DL, TII->get(AMDGPU::V_READFIRSTLANE_B32), RegOp1)
7045 .addReg(Src1.getReg());
7046 Src1.setReg(RegOp1);
7047 }
7048 Register RegOp2 = MRI.createVirtualRegister(&AMDGPU::SReg_32_XM0RegClass);
7049 if (TRI->isVectorRegister(MRI, Src2.getReg())) {
7050 BuildMI(*BB, MII, DL, TII->get(AMDGPU::V_READFIRSTLANE_B32), RegOp2)
7051 .addReg(Src2.getReg());
7052 Src2.setReg(RegOp2);
7053 }
7054
7055 if (ST.isWave64()) {
7056 if (ST.hasScalarCompareEq64()) {
7057 BuildMI(*BB, MII, DL, TII->get(AMDGPU::S_CMP_LG_U64))
7058 .addReg(Src2.getReg())
7059 .addImm(0);
7060 } else {
7061 const TargetRegisterClass *Src2RC = MRI.getRegClass(Src2.getReg());
7062 const TargetRegisterClass *SubRC =
7063 TRI->getSubRegisterClass(Src2RC, AMDGPU::sub0);
7064 MachineOperand Src2Sub0 = TII->buildExtractSubRegOrImm(
7065 MII, MRI, Src2, Src2RC, AMDGPU::sub0, SubRC);
7066 MachineOperand Src2Sub1 = TII->buildExtractSubRegOrImm(
7067 MII, MRI, Src2, Src2RC, AMDGPU::sub1, SubRC);
7068 Register Src2_32 = MRI.createVirtualRegister(&AMDGPU::SReg_32RegClass);
7069
7070 BuildMI(*BB, MII, DL, TII->get(AMDGPU::S_OR_B32), Src2_32)
7071 .add(Src2Sub0)
7072 .add(Src2Sub1);
7073
7074 BuildMI(*BB, MII, DL, TII->get(AMDGPU::S_CMP_LG_U32))
7075 .addReg(Src2_32, RegState::Kill)
7076 .addImm(0);
7077 }
7078 } else {
7079 BuildMI(*BB, MII, DL, TII->get(AMDGPU::S_CMP_LG_U32))
7080 .addReg(Src2.getReg())
7081 .addImm(0);
7082 }
7083
7084 unsigned Opc = MI.getOpcode() == AMDGPU::S_ADD_CO_PSEUDO
7085 ? AMDGPU::S_ADDC_U32
7086 : AMDGPU::S_SUBB_U32;
7087
7088 BuildMI(*BB, MII, DL, TII->get(Opc), Dest.getReg()).add(Src0).add(Src1);
7089
7090 unsigned SelOpc =
7091 ST.isWave64() ? AMDGPU::S_CSELECT_B64 : AMDGPU::S_CSELECT_B32;
7092
7093 BuildMI(*BB, MII, DL, TII->get(SelOpc), CarryDest.getReg())
7094 .addImm(-1)
7095 .addImm(0);
7096
7097 MI.eraseFromParent();
7098 return BB;
7099 }
7100 case AMDGPU::SI_INIT_M0: {
7101 MachineOperand &M0Init = MI.getOperand(0);
7102 BuildMI(*BB, MI.getIterator(), MI.getDebugLoc(),
7103 TII->get(M0Init.isReg() ? AMDGPU::COPY : AMDGPU::S_MOV_B32),
7104 AMDGPU::M0)
7105 .add(M0Init);
7106 MI.eraseFromParent();
7107 return BB;
7108 }
7109 case AMDGPU::S_BARRIER_SIGNAL_ISFIRST_IMM: {
7110 // Set SCC to true, in case the barrier instruction gets converted to a NOP.
7111 BuildMI(*BB, MI.getIterator(), MI.getDebugLoc(),
7112 TII->get(AMDGPU::S_CMP_EQ_U32))
7113 .addImm(0)
7114 .addImm(0);
7115 return BB;
7116 }
7117 case AMDGPU::GET_GROUPSTATICSIZE: {
7118 assert(getTargetMachine().getTargetTriple().getOS() == Triple::AMDHSA ||
7119 getTargetMachine().getTargetTriple().getOS() == Triple::AMDPAL);
7120 BuildMI(*BB, MI, DL, TII->get(AMDGPU::S_MOV_B32))
7121 .add(MI.getOperand(0))
7122 .addImm(MFI->getLDSSize());
7123 MI.eraseFromParent();
7124 return BB;
7125 }
7126 case AMDGPU::GET_SHADERCYCLESHILO: {
7127 assert(MF->getSubtarget<GCNSubtarget>().hasShaderCyclesHiLoRegisters());
7128 // The algorithm is:
7129 //
7130 // hi1 = getreg(SHADER_CYCLES_HI)
7131 // lo1 = getreg(SHADER_CYCLES_LO)
7132 // hi2 = getreg(SHADER_CYCLES_HI)
7133 //
7134 // If hi1 == hi2 then there was no overflow and the result is hi2:lo1.
7135 // Otherwise there was overflow and the result is hi2:0. In both cases the
7136 // result should represent the actual time at some point during the sequence
7137 // of three getregs.
7138 using namespace AMDGPU::Hwreg;
7139 Register RegHi1 = MRI.createVirtualRegister(&AMDGPU::SReg_32RegClass);
7140 BuildMI(*BB, MI, DL, TII->get(AMDGPU::S_GETREG_B32), RegHi1)
7141 .addImm(HwregEncoding::encode(ID_SHADER_CYCLES_HI, 0, 32));
7142 Register RegLo1 = MRI.createVirtualRegister(&AMDGPU::SReg_32RegClass);
7143 BuildMI(*BB, MI, DL, TII->get(AMDGPU::S_GETREG_B32), RegLo1)
7144 .addImm(HwregEncoding::encode(ID_SHADER_CYCLES, 0, 32));
7145 Register RegHi2 = MRI.createVirtualRegister(&AMDGPU::SReg_32RegClass);
7146 BuildMI(*BB, MI, DL, TII->get(AMDGPU::S_GETREG_B32), RegHi2)
7147 .addImm(HwregEncoding::encode(ID_SHADER_CYCLES_HI, 0, 32));
7148 BuildMI(*BB, MI, DL, TII->get(AMDGPU::S_CMP_EQ_U32))
7149 .addReg(RegHi1)
7150 .addReg(RegHi2);
7151 Register RegLo = MRI.createVirtualRegister(&AMDGPU::SReg_32RegClass);
7152 BuildMI(*BB, MI, DL, TII->get(AMDGPU::S_CSELECT_B32), RegLo)
7153 .addReg(RegLo1)
7154 .addImm(0);
7155 BuildMI(*BB, MI, DL, TII->get(AMDGPU::REG_SEQUENCE))
7156 .add(MI.getOperand(0))
7157 .addReg(RegLo)
7158 .addImm(AMDGPU::sub0)
7159 .addReg(RegHi2)
7160 .addImm(AMDGPU::sub1);
7161 MI.eraseFromParent();
7162 return BB;
7163 }
7164 case AMDGPU::SI_INDIRECT_SRC_V1:
7165 case AMDGPU::SI_INDIRECT_SRC_V2:
7166 case AMDGPU::SI_INDIRECT_SRC_V3:
7167 case AMDGPU::SI_INDIRECT_SRC_V4:
7168 case AMDGPU::SI_INDIRECT_SRC_V5:
7169 case AMDGPU::SI_INDIRECT_SRC_V6:
7170 case AMDGPU::SI_INDIRECT_SRC_V7:
7171 case AMDGPU::SI_INDIRECT_SRC_V8:
7172 case AMDGPU::SI_INDIRECT_SRC_V9:
7173 case AMDGPU::SI_INDIRECT_SRC_V10:
7174 case AMDGPU::SI_INDIRECT_SRC_V11:
7175 case AMDGPU::SI_INDIRECT_SRC_V12:
7176 case AMDGPU::SI_INDIRECT_SRC_V16:
7177 case AMDGPU::SI_INDIRECT_SRC_V32:
7178 return emitIndirectSrc(MI, *BB, *getSubtarget());
7179 case AMDGPU::SI_INDIRECT_DST_V1:
7180 case AMDGPU::SI_INDIRECT_DST_V2:
7181 case AMDGPU::SI_INDIRECT_DST_V3:
7182 case AMDGPU::SI_INDIRECT_DST_V4:
7183 case AMDGPU::SI_INDIRECT_DST_V5:
7184 case AMDGPU::SI_INDIRECT_DST_V6:
7185 case AMDGPU::SI_INDIRECT_DST_V7:
7186 case AMDGPU::SI_INDIRECT_DST_V8:
7187 case AMDGPU::SI_INDIRECT_DST_V9:
7188 case AMDGPU::SI_INDIRECT_DST_V10:
7189 case AMDGPU::SI_INDIRECT_DST_V11:
7190 case AMDGPU::SI_INDIRECT_DST_V12:
7191 case AMDGPU::SI_INDIRECT_DST_V16:
7192 case AMDGPU::SI_INDIRECT_DST_V32:
7193 return emitIndirectDst(MI, *BB, *getSubtarget());
7194 case AMDGPU::SI_KILL_F32_COND_IMM_PSEUDO:
7195 case AMDGPU::SI_KILL_I1_PSEUDO:
7196 return splitKillBlock(MI, BB);
7197 case AMDGPU::V_CNDMASK_B64_PSEUDO: {
7199 return BB;
7200 }
7201 case AMDGPU::SI_BR_UNDEF: {
7202 MachineInstr *Br = BuildMI(*BB, MI, DL, TII->get(AMDGPU::S_CBRANCH_SCC1))
7203 .add(MI.getOperand(0));
7204 Br->getOperand(1).setIsUndef(); // read undef SCC
7205 MI.eraseFromParent();
7206 return BB;
7207 }
7208 case AMDGPU::ADJCALLSTACKUP:
7209 case AMDGPU::ADJCALLSTACKDOWN: {
7211 MachineInstrBuilder MIB(*MF, &MI);
7212 MIB.addReg(Info->getStackPtrOffsetReg(), RegState::ImplicitDefine)
7213 .addReg(Info->getStackPtrOffsetReg(), RegState::Implicit);
7214 return BB;
7215 }
7216 case AMDGPU::SI_CALL_ISEL: {
7217 unsigned ReturnAddrReg = TII->getRegisterInfo().getReturnAddressReg(*MF);
7218
7220 MIB = BuildMI(*BB, MI, DL, TII->get(AMDGPU::SI_CALL), ReturnAddrReg);
7221
7222 for (const MachineOperand &MO : MI.operands())
7223 MIB.add(MO);
7224
7225 MIB.cloneMemRefs(MI);
7226 MI.eraseFromParent();
7227 return BB;
7228 }
7229 case AMDGPU::V_ADD_CO_U32_e32:
7230 case AMDGPU::V_SUB_CO_U32_e32:
7231 case AMDGPU::V_SUBREV_CO_U32_e32: {
7232 // TODO: Define distinct V_*_I32_Pseudo instructions instead.
7233 unsigned Opc = MI.getOpcode();
7234
7235 bool NeedClampOperand = false;
7236 if (TII->pseudoToMCOpcode(Opc) == -1) {
7238 NeedClampOperand = true;
7239 }
7240
7241 auto I = BuildMI(*BB, MI, DL, TII->get(Opc), MI.getOperand(0).getReg());
7242 if (TII->isVOP3(*I)) {
7243 I.addReg(TRI->getVCC(), RegState::Define);
7244 }
7245 I.add(MI.getOperand(1)).add(MI.getOperand(2));
7246 if (NeedClampOperand)
7247 I.addImm(0); // clamp bit for e64 encoding
7248
7249 TII->legalizeOperands(*I);
7250
7251 MI.eraseFromParent();
7252 return BB;
7253 }
7254 case AMDGPU::V_ADDC_U32_e32:
7255 case AMDGPU::V_SUBB_U32_e32:
7256 case AMDGPU::V_SUBBREV_U32_e32:
7257 // These instructions have an implicit use of vcc which counts towards the
7258 // constant bus limit.
7259 TII->legalizeOperands(MI);
7260 return BB;
7261 case AMDGPU::DS_GWS_INIT:
7262 case AMDGPU::DS_GWS_SEMA_BR:
7263 case AMDGPU::DS_GWS_BARRIER:
7264 case AMDGPU::DS_GWS_SEMA_V:
7265 case AMDGPU::DS_GWS_SEMA_P:
7266 case AMDGPU::DS_GWS_SEMA_RELEASE_ALL:
7267 // A s_waitcnt 0 is required to be the instruction immediately following.
7268 if (getSubtarget()->hasGWSAutoReplay()) {
7270 return BB;
7271 }
7272
7273 return emitGWSMemViolTestLoop(MI, BB);
7274 case AMDGPU::S_SETREG_B32: {
7275 // Try to optimize cases that only set the denormal mode or rounding mode.
7276 //
7277 // If the s_setreg_b32 fully sets all of the bits in the rounding mode or
7278 // denormal mode to a constant, we can use s_round_mode or s_denorm_mode
7279 // instead.
7280 //
7281 // FIXME: This could be predicates on the immediate, but tablegen doesn't
7282 // allow you to have a no side effect instruction in the output of a
7283 // sideeffecting pattern.
7284 auto [ID, Offset, Width] =
7285 AMDGPU::Hwreg::HwregEncoding::decode(MI.getOperand(1).getImm());
7286 if (ID != AMDGPU::Hwreg::ID_MODE)
7287 return BB;
7288
7289 const unsigned WidthMask = maskTrailingOnes<unsigned>(Width);
7290 const unsigned SetMask = WidthMask << Offset;
7291
7292 if (getSubtarget()->hasDenormModeInst()) {
7293 unsigned SetDenormOp = 0;
7294 unsigned SetRoundOp = 0;
7295
7296 // The dedicated instructions can only set the whole denorm or round mode
7297 // at once, not a subset of bits in either.
7298 if (SetMask ==
7300 // If this fully sets both the round and denorm mode, emit the two
7301 // dedicated instructions for these.
7302 SetRoundOp = AMDGPU::S_ROUND_MODE;
7303 SetDenormOp = AMDGPU::S_DENORM_MODE;
7304 } else if (SetMask == AMDGPU::Hwreg::FP_ROUND_MASK) {
7305 SetRoundOp = AMDGPU::S_ROUND_MODE;
7306 } else if (SetMask == AMDGPU::Hwreg::FP_DENORM_MASK) {
7307 SetDenormOp = AMDGPU::S_DENORM_MODE;
7308 }
7309
7310 if (SetRoundOp || SetDenormOp) {
7311 MachineInstr *Def = MRI.getVRegDef(MI.getOperand(0).getReg());
7312 if (Def && Def->isMoveImmediate() && Def->getOperand(1).isImm()) {
7313 unsigned ImmVal = Def->getOperand(1).getImm();
7314 if (SetRoundOp) {
7315 BuildMI(*BB, MI, MI.getDebugLoc(), TII->get(SetRoundOp))
7316 .addImm(ImmVal & 0xf);
7317
7318 // If we also have the denorm mode, get just the denorm mode bits.
7319 ImmVal >>= 4;
7320 }
7321
7322 if (SetDenormOp) {
7323 BuildMI(*BB, MI, MI.getDebugLoc(), TII->get(SetDenormOp))
7324 .addImm(ImmVal & 0xf);
7325 }
7326
7327 MI.eraseFromParent();
7328 return BB;
7329 }
7330 }
7331 }
7332
7333 // If only FP bits are touched, used the no side effects pseudo.
7334 if ((SetMask & (AMDGPU::Hwreg::FP_ROUND_MASK |
7335 AMDGPU::Hwreg::FP_DENORM_MASK)) == SetMask)
7336 MI.setDesc(TII->get(AMDGPU::S_SETREG_B32_mode));
7337
7338 return BB;
7339 }
7340 case AMDGPU::S_INVERSE_BALLOT_U32:
7341 case AMDGPU::S_INVERSE_BALLOT_U64:
7342 // These opcodes only exist to let SIFixSGPRCopies insert a readfirstlane if
7343 // necessary. After that they are equivalent to a COPY.
7344 MI.setDesc(TII->get(AMDGPU::COPY));
7345 return BB;
7346 case AMDGPU::ENDPGM_TRAP: {
7347 if (BB->succ_empty() && std::next(MI.getIterator()) == BB->end()) {
7348 MI.setDesc(TII->get(AMDGPU::S_ENDPGM));
7349 MI.addOperand(MachineOperand::CreateImm(0));
7350 return BB;
7351 }
7352
7353 // We need a block split to make the real endpgm a terminator. We also don't
7354 // want to break phis in successor blocks, so we can't just delete to the
7355 // end of the block.
7356
7357 MachineBasicBlock *SplitBB = BB->splitAt(MI, false /*UpdateLiveIns*/);
7359 MF->push_back(TrapBB);
7360 // clang-format off
7361 BuildMI(*TrapBB, TrapBB->end(), DL, TII->get(AMDGPU::S_ENDPGM))
7362 .addImm(0);
7363 BuildMI(*BB, &MI, DL, TII->get(AMDGPU::S_CBRANCH_EXECNZ))
7364 .addMBB(TrapBB);
7365 // clang-format on
7366
7367 BB->addSuccessor(TrapBB);
7368 MI.eraseFromParent();
7369 return SplitBB;
7370 }
7371 case AMDGPU::SIMULATED_TRAP: {
7372 assert(Subtarget->hasPrivEnabledTrap2NopBug());
7373 MachineBasicBlock *SplitBB =
7374 TII->insertSimulatedTrap(MRI, *BB, MI, MI.getDebugLoc());
7375 MI.eraseFromParent();
7376 return SplitBB;
7377 }
7378 case AMDGPU::SI_TCRETURN_GFX_WholeWave:
7379 case AMDGPU::SI_WHOLE_WAVE_FUNC_RETURN: {
7381
7382 // During ISel, it's difficult to propagate the original EXEC mask to use as
7383 // an input to SI_WHOLE_WAVE_FUNC_RETURN. Set it up here instead.
7384 MachineInstr *Setup = TII->getWholeWaveFunctionSetup(*BB->getParent());
7385 assert(Setup && "Couldn't find SI_SETUP_WHOLE_WAVE_FUNC");
7386 Register OriginalExec = Setup->getOperand(0).getReg();
7387 MF->getRegInfo().clearKillFlags(OriginalExec);
7388 MI.getOperand(0).setReg(OriginalExec);
7389 return BB;
7390 }
7391 case AMDGPU::V_DOT2_F32_F16:
7392 case AMDGPU::V_DOT2_F32_BF16: {
7393 // Hint RA to assign dst and src2 the same physical register.
7394 // For targets without VOP2, but with VOPD, variant of the instruction this
7395 // is one of the conditions to attempt converting VOP3P to VOPD.
7396 MRI.setSimpleHint(MI.getOperand(0).getReg(), MI.getOperand(6).getReg());
7397 return BB;
7398 }
7399 default:
7400 if (TII->isImage(MI) || TII->isMUBUF(MI)) {
7401 if (!MI.mayStore())
7403 return BB;
7404 }
7406 }
7407}
7408
7410 // This currently forces unfolding various combinations of fsub into fma with
7411 // free fneg'd operands. As long as we have fast FMA (controlled by
7412 // isFMAFasterThanFMulAndFAdd), we should perform these.
7413
7414 // When fma is quarter rate, for f64 where add / sub are at best half rate,
7415 // most of these combines appear to be cycle neutral but save on instruction
7416 // count / code size.
7417 return true;
7418}
7419
7421
7423 EVT VT) const {
7424 if (!VT.isVector()) {
7425 return MVT::i1;
7426 }
7427 return EVT::getVectorVT(Ctx, MVT::i1, VT.getVectorNumElements());
7428}
7429
7431 // TODO: Should i16 be used always if legal? For now it would force VALU
7432 // shifts.
7433 return (VT == MVT::i16) ? MVT::i16 : MVT::i32;
7434}
7435
7437 return (Ty.getScalarSizeInBits() <= 16 && Subtarget->has16BitInsts())
7438 ? Ty.changeElementSize(16)
7439 : Ty.changeElementSize(32);
7440}
7441
7442// Answering this is somewhat tricky and depends on the specific device which
7443// have different rates for fma or all f64 operations.
7444//
7445// v_fma_f64 and v_mul_f64 always take the same number of cycles as each other
7446// regardless of which device (although the number of cycles differs between
7447// devices), so it is always profitable for f64.
7448//
7449// v_fma_f32 takes 4 or 16 cycles depending on the device, so it is profitable
7450// only on full rate devices. Normally, we should prefer selecting v_mad_f32
7451// which we can always do even without fused FP ops since it returns the same
7452// result as the separate operations and since it is always full
7453// rate. Therefore, we lie and report that it is not faster for f32. v_mad_f32
7454// however does not support denormals, so we do report fma as faster if we have
7455// a fast fma device and require denormals.
7456//
7458 DenormalFPEnv FPEnv) const {
7459 VT = VT.getScalarType();
7460 if (!VT.isSimple())
7461 return false;
7462
7463 switch (VT.getSimpleVT().SimpleTy) {
7464 case MVT::f32: {
7465 // If mad is not available this depends only on if f32 fma is full rate.
7466 if (!Subtarget->hasMadMacF32Insts())
7467 return Subtarget->hasFastFMAF32();
7468
7469 // Otherwise f32 mad is always full rate and returns the same result as
7470 // the separate operations so should be preferred over fma.
7471 // However does not support denormals.
7473 return Subtarget->hasFastFMAF32() || Subtarget->hasDLInsts();
7474
7475 // If the subtarget has v_fmac_f32, that's just as good as v_mac_f32.
7476 return Subtarget->hasFastFMAF32() && Subtarget->hasDLInsts();
7477 }
7478 case MVT::f64:
7479 return true;
7480 case MVT::f16:
7481 case MVT::bf16:
7482 return Subtarget->has16BitInsts() &&
7484 default:
7485 break;
7486 }
7487
7488 return false;
7489}
7490
7495
7497 Type *Ty) const {
7499 getValueType(F.getDataLayout(), Ty, /*AllowUnknown=*/true),
7500 F.getDenormalFPEnv());
7501}
7502
7504 LLT Ty) const {
7505 switch (Ty.getScalarSizeInBits()) {
7506 case 16:
7507 return isFMAFasterThanFMulAndFAdd(MF, MVT::f16);
7508 case 32:
7509 return isFMAFasterThanFMulAndFAdd(MF, MVT::f32);
7510 case 64:
7511 return isFMAFasterThanFMulAndFAdd(MF, MVT::f64);
7512 default:
7513 break;
7514 }
7515
7516 return false;
7517}
7518
7520 // TODO: Check future ftz flag
7521 // v_mad_f32/v_mac_f32 do not support denormals.
7522 if (VT == MVT::f32)
7523 return Subtarget->hasMadMacF32Insts() &&
7525 if (VT == MVT::f16)
7526 return Subtarget->hasMadF16() &&
7528
7529 return false;
7530}
7531
7533 if (!Ty.isScalar())
7534 return false;
7535
7536 DenormalFPEnv FPEnv = getDenormalFPEnv(*MI.getMF());
7537 if (Ty.getScalarSizeInBits() == 16)
7538 return isFMADLegal(MVT::f16, FPEnv);
7539 if (Ty.getScalarSizeInBits() == 32)
7540 return isFMADLegal(MVT::f32, FPEnv);
7541
7542 return false;
7543}
7544
7546 const SDNode *N) const {
7547 return isFMADLegal(N->getValueType(0),
7549}
7550
7551//===----------------------------------------------------------------------===//
7552// Custom DAG Lowering Operations
7553//===----------------------------------------------------------------------===//
7554
7555// Work around LegalizeDAG doing the wrong thing and fully scalarizing if the
7556// wider vector type is legal.
7558 SelectionDAG &DAG) const {
7559 unsigned Opc = Op.getOpcode();
7560 EVT VT = Op.getValueType();
7562
7563 auto [Lo, Hi] = DAG.SplitVectorOperand(Op.getNode(), 0);
7564 auto [LoVT, HiVT] = DAG.GetSplitDestVTs(VT);
7565
7566 SDLoc SL(Op);
7567
7568 // Forward any trailing scalar operands unchanged to both halves.
7569 SmallVector<SDValue, 2> LoOps = {Lo};
7570 SmallVector<SDValue, 2> HiOps = {Hi};
7571 auto TrailingOps = drop_begin(Op->ops());
7572 LoOps.append(TrailingOps.begin(), TrailingOps.end());
7573 HiOps.append(TrailingOps.begin(), TrailingOps.end());
7574
7575 SDValue OpLo = DAG.getNode(Opc, SL, LoVT, LoOps, Op->getFlags());
7576 SDValue OpHi = DAG.getNode(Opc, SL, HiVT, HiOps, Op->getFlags());
7577
7578 return DAG.getNode(ISD::CONCAT_VECTORS, SDLoc(Op), VT, OpLo, OpHi);
7579}
7580
7581// Enable lowering of ROTR for vxi32 types. This is a workaround for a
7582// regression whereby extra unnecessary instructions were added to codegen
7583// for rotr operations, casued by legalising v2i32 or. This resulted in extra
7584// instructions to extract the result from the vector.
7586 [[maybe_unused]] EVT VT = Op.getValueType();
7587
7588 assert((VT == MVT::v2i32 || VT == MVT::v4i32 || VT == MVT::v8i32 ||
7589 VT == MVT::v16i32) &&
7590 "Unexpected ValueType.");
7591
7592 return DAG.UnrollVectorOp(Op.getNode());
7593}
7594
7595// Work around LegalizeDAG doing the wrong thing and fully scalarizing if the
7596// wider vector type is legal.
7598 SelectionDAG &DAG) const {
7599 unsigned Opc = Op.getOpcode();
7600 EVT VT = Op.getValueType();
7602
7603 auto [Lo0, Hi0] = DAG.SplitVectorOperand(Op.getNode(), 0);
7604 auto [Lo1, Hi1] = DAG.SplitVectorOperand(Op.getNode(), 1);
7605
7606 SDLoc SL(Op);
7607
7608 SDValue OpLo =
7609 DAG.getNode(Opc, SL, Lo0.getValueType(), Lo0, Lo1, Op->getFlags());
7610 SDValue OpHi =
7611 DAG.getNode(Opc, SL, Hi0.getValueType(), Hi0, Hi1, Op->getFlags());
7612
7613 return DAG.getNode(ISD::CONCAT_VECTORS, SDLoc(Op), VT, OpLo, OpHi);
7614}
7615
7617 SelectionDAG &DAG) const {
7618 unsigned Opc = Op.getOpcode();
7619 EVT VT = Op.getValueType();
7621
7622 SDValue Op0 = Op.getOperand(0);
7623 auto [Lo0, Hi0] = Op0.getValueType().isVector()
7624 ? DAG.SplitVectorOperand(Op.getNode(), 0)
7625 : std::pair(Op0, Op0);
7626
7627 auto [Lo1, Hi1] = DAG.SplitVectorOperand(Op.getNode(), 1);
7628 auto [Lo2, Hi2] = DAG.SplitVectorOperand(Op.getNode(), 2);
7629
7630 SDLoc SL(Op);
7631 auto ResVT = DAG.GetSplitDestVTs(VT);
7632
7633 SDValue OpLo =
7634 DAG.getNode(Opc, SL, ResVT.first, Lo0, Lo1, Lo2, Op->getFlags());
7635 SDValue OpHi =
7636 DAG.getNode(Opc, SL, ResVT.second, Hi0, Hi1, Hi2, Op->getFlags());
7637
7638 return DAG.getNode(ISD::CONCAT_VECTORS, SDLoc(Op), VT, OpLo, OpHi);
7639}
7640
7642 switch (Op.getOpcode()) {
7643 default:
7645 case ISD::BRCOND:
7646 return LowerBRCOND(Op, DAG);
7647 case ISD::RETURNADDR:
7648 return LowerRETURNADDR(Op, DAG);
7649 case ISD::SPONENTRY:
7650 return LowerSPONENTRY(Op, DAG);
7651 case ISD::LOAD: {
7652 SDValue Result = LowerLOAD(Op, DAG);
7653 assert((!Result.getNode() || Result.getNode()->getNumValues() == 2) &&
7654 "Load should return a value and a chain");
7655 return Result;
7656 }
7657 case ISD::FSQRT: {
7658 EVT VT = Op.getValueType();
7659 if (VT == MVT::f32)
7660 return lowerFSQRTF32(Op, DAG);
7661 if (VT == MVT::f64)
7662 return lowerFSQRTF64(Op, DAG);
7663 return SDValue();
7664 }
7665 case ISD::FSIN:
7666 case ISD::FCOS:
7667 return LowerTrig(Op, DAG);
7668 case ISD::SELECT:
7669 return LowerSELECT(Op, DAG);
7670 case ISD::FDIV:
7671 return LowerFDIV(Op, DAG);
7672 case ISD::FFREXP:
7673 return LowerFFREXP(Op, DAG);
7675 return LowerATOMIC_CMP_SWAP(Op, DAG);
7676 case ISD::STORE:
7677 return LowerSTORE(Op, DAG);
7678 case ISD::GlobalAddress: {
7681 return LowerGlobalAddress(MFI, Op, DAG);
7682 }
7683 case ISD::BlockAddress:
7684 return LowerBlockAddress(Op, DAG);
7686 return LowerExternalSymbol(Op, DAG);
7688 return LowerINTRINSIC_WO_CHAIN(Op, DAG);
7690 return LowerCONVERT_FROM_ARBITRARY_FP(Op, DAG);
7692 return LowerCONVERT_TO_ARBITRARY_FP(Op, DAG);
7694 return LowerINTRINSIC_W_CHAIN(Op, DAG);
7696 return LowerINTRINSIC_VOID(Op, DAG);
7697 case ISD::ADDRSPACECAST:
7698 return lowerADDRSPACECAST(Op, DAG);
7700 return lowerINSERT_SUBVECTOR(Op, DAG);
7702 return lowerINSERT_VECTOR_ELT(Op, DAG);
7704 return lowerEXTRACT_VECTOR_ELT(Op, DAG);
7706 return lowerVECTOR_SHUFFLE(Op, DAG);
7708 return lowerSCALAR_TO_VECTOR(Op, DAG);
7709 case ISD::BUILD_VECTOR:
7710 return lowerBUILD_VECTOR(Op, DAG);
7711 case ISD::FP_ROUND:
7713 return lowerFP_ROUND(Op, DAG);
7714 case ISD::TRAP:
7715 return lowerTRAP(Op, DAG);
7716 case ISD::DEBUGTRAP:
7717 return lowerDEBUGTRAP(Op, DAG);
7718 case ISD::ABS:
7719 case ISD::FABS:
7720 case ISD::FNEG:
7721 case ISD::FCANONICALIZE:
7722 case ISD::BSWAP:
7723 return splitUnaryVectorOp(Op, DAG);
7726 if (Op.getValueType().isVector() && Op.getValueType() != MVT::v2i16 &&
7727 Op.getOperand(0).getValueType().getScalarType() == MVT::f32)
7728 return splitUnaryVectorOp(Op, DAG);
7729 return LowerFP_TO_INT_SAT(Op, DAG);
7730 case ISD::FSUB:
7731 if (Op.getValueType() == MVT::bf16) {
7732 // Custom expansion:
7733 // fsub bf16 %a, %b -> fadd v2bf16(widen %a), fneg v2bf16(widen %b)
7734 // Then extract back to bf16.
7735 //
7736 // We create fneg on v2bf16 (not bf16) so the instruction selector can
7737 // fold the negation into the packed add's neg_lo/neg_hi modifiers,
7738 // generating a single v_pk_add_bf16 instruction. If we negate bf16 first,
7739 // it becomes a separate v_xor instruction before widening.
7740 SDLoc DL(Op);
7741 SDValue Op0 = Op.getOperand(0);
7742 SDValue Op1 = Op.getOperand(1);
7743
7744 // Widen both operands to v2bf16
7745 SDValue Vec0 = DAG.getNode(ISD::SCALAR_TO_VECTOR, DL, MVT::v2bf16, Op0);
7746 SDValue Vec1 = DAG.getNode(ISD::SCALAR_TO_VECTOR, DL, MVT::v2bf16, Op1);
7747
7748 // Create FNEG v2bf16 for the second operand
7749 SDValue NegVec1 = DAG.getNode(ISD::FNEG, DL, MVT::v2bf16, Vec1);
7750
7751 // Perform FADD v2bf16
7752 SDValue Result = DAG.getNode(ISD::FADD, DL, MVT::v2bf16, Vec0, NegVec1);
7753
7754 // Extract element 0 back to bf16
7755 return DAG.getNode(ISD::EXTRACT_VECTOR_ELT, DL, MVT::bf16, Result,
7756 DAG.getConstant(0, DL, MVT::i32));
7757 }
7758 return SDValue();
7759 case ISD::FMINNUM:
7760 case ISD::FMAXNUM:
7761 return lowerFMINNUM_FMAXNUM(Op, DAG);
7762 case ISD::FMINIMUMNUM:
7763 case ISD::FMAXIMUMNUM:
7764 return lowerFMINIMUMNUM_FMAXIMUMNUM(Op, DAG);
7765 case ISD::FLDEXP:
7766 case ISD::STRICT_FLDEXP:
7767 return lowerFLDEXP(Op, DAG);
7768 case ISD::FMA:
7769 return splitTernaryVectorOp(Op, DAG);
7770 case ISD::FP_TO_SINT:
7771 case ISD::FP_TO_UINT:
7772 if (Subtarget->hasVCvtPkIU16F32() && Op.getValueType() == MVT::i16 &&
7773 Op.getOperand(0).getValueType() == MVT::f32) {
7774 // Make f32->i16 legal so we can select V_CVT_PK_[IU]16_F32.
7775 return Op;
7776 }
7777 return LowerFP_TO_INT(Op, DAG);
7778 case ISD::SHL:
7779 case ISD::SRA:
7780 case ISD::SRL:
7781 case ISD::ADD:
7782 case ISD::SUB:
7783 case ISD::SMIN:
7784 case ISD::SMAX:
7785 case ISD::UMIN:
7786 case ISD::UMAX:
7787 case ISD::FMINNUM_IEEE:
7788 case ISD::FMAXNUM_IEEE:
7789 case ISD::FMINIMUM:
7790 case ISD::FMAXIMUM:
7791 case ISD::UADDSAT:
7792 case ISD::USUBSAT:
7793 case ISD::SADDSAT:
7794 case ISD::SSUBSAT:
7795 case ISD::FADD:
7796 case ISD::FMUL:
7797 return splitBinaryVectorOp(Op, DAG);
7798 case ISD::FCOPYSIGN:
7799 return lowerFCOPYSIGN(Op, DAG);
7800 case ISD::MUL:
7801 return lowerMUL(Op, DAG);
7802 case ISD::SMULO:
7803 case ISD::UMULO:
7804 return lowerXMULO(Op, DAG);
7805 case ISD::SMUL_LOHI:
7806 case ISD::UMUL_LOHI:
7807 return lowerXMUL_LOHI(Op, DAG);
7809 return LowerDYNAMIC_STACKALLOC(Op, DAG);
7810 case ISD::STACKSAVE:
7811 return LowerSTACKSAVE(Op, DAG);
7812 case ISD::GET_ROUNDING:
7813 return lowerGET_ROUNDING(Op, DAG);
7814 case ISD::SET_ROUNDING:
7815 return lowerSET_ROUNDING(Op, DAG);
7816 case ISD::PREFETCH:
7817 return lowerPREFETCH(Op, DAG);
7818 case ISD::FP_EXTEND:
7820 return lowerFP_EXTEND(Op, DAG);
7821 case ISD::GET_FPENV:
7822 return lowerGET_FPENV(Op, DAG);
7823 case ISD::SET_FPENV:
7824 return lowerSET_FPENV(Op, DAG);
7825 case ISD::ROTR:
7826 return lowerROTR(Op, DAG);
7827 case ISD::INLINEASM:
7828 return LowerINLINEASM(Op, DAG);
7829 }
7830 return SDValue();
7831}
7832
7833// Used for D16: Casts the result of an instruction into the right vector,
7834// packs values if loads return unpacked values.
7836 const SDLoc &DL, SelectionDAG &DAG,
7837 bool Unpacked) {
7838 if (!LoadVT.isVector())
7839 return Result;
7840
7841 // Cast back to the original packed type or to a larger type that is a
7842 // multiple of 32 bit for D16. Widening the return type is a required for
7843 // legalization.
7844 EVT FittingLoadVT = LoadVT;
7845 if ((LoadVT.getVectorNumElements() % 2) == 1) {
7846 FittingLoadVT =
7848 LoadVT.getVectorNumElements() + 1);
7849 }
7850
7851 if (Unpacked) { // From v2i32/v4i32 back to v2f16/v4f16.
7852 // Truncate to v2i16/v4i16.
7853 EVT IntLoadVT = FittingLoadVT.changeTypeToInteger();
7854
7855 // Workaround legalizer not scalarizing truncate after vector op
7856 // legalization but not creating intermediate vector trunc.
7858 DAG.ExtractVectorElements(Result, Elts);
7859 for (SDValue &Elt : Elts)
7860 Elt = DAG.getNode(ISD::TRUNCATE, DL, MVT::i16, Elt);
7861
7862 // Pad illegal v1i16/v3fi6 to v4i16
7863 if ((LoadVT.getVectorNumElements() % 2) == 1)
7864 Elts.push_back(DAG.getPOISON(MVT::i16));
7865
7866 Result = DAG.getBuildVector(IntLoadVT, DL, Elts);
7867
7868 // Bitcast to original type (v2f16/v4f16).
7869 return DAG.getNode(ISD::BITCAST, DL, FittingLoadVT, Result);
7870 }
7871
7872 // Cast back to the original packed type.
7873 return DAG.getNode(ISD::BITCAST, DL, FittingLoadVT, Result);
7874}
7875
7876SDValue SITargetLowering::adjustLoadValueType(unsigned Opcode, MemSDNode *M,
7877 SelectionDAG &DAG,
7879 bool IsIntrinsic) const {
7880 SDLoc DL(M);
7881
7882 bool Unpacked = Subtarget->hasUnpackedD16VMem();
7883 EVT LoadVT = M->getValueType(0);
7884
7885 EVT EquivLoadVT = LoadVT;
7886 if (LoadVT.isVector()) {
7887 if (Unpacked) {
7888 EquivLoadVT = EVT::getVectorVT(*DAG.getContext(), MVT::i32,
7889 LoadVT.getVectorNumElements());
7890 } else if ((LoadVT.getVectorNumElements() % 2) == 1) {
7891 // Widen v3f16 to legal type
7892 EquivLoadVT =
7894 LoadVT.getVectorNumElements() + 1);
7895 }
7896 }
7897
7898 // Change from v4f16/v2f16 to EquivLoadVT.
7899 SDVTList VTList = DAG.getVTList(EquivLoadVT, MVT::Other);
7900
7902 IsIntrinsic ? (unsigned)ISD::INTRINSIC_W_CHAIN : Opcode, DL, VTList, Ops,
7903 M->getMemoryVT(), M->getMemOperand());
7904
7905 SDValue Adjusted = adjustLoadValueTypeImpl(Load, LoadVT, DL, DAG, Unpacked);
7906
7907 return DAG.getMergeValues({Adjusted, Load.getValue(1)}, DL);
7908}
7909
7910SDValue SITargetLowering::lowerIntrinsicLoad(MemSDNode *M, bool IsFormat,
7911 SelectionDAG &DAG,
7912 ArrayRef<SDValue> Ops) const {
7913 SDLoc DL(M);
7914 EVT LoadVT = M->getValueType(0);
7915 EVT EltType = LoadVT.getScalarType();
7916 EVT IntVT = LoadVT.changeTypeToInteger();
7917
7918 bool IsD16 = IsFormat && (EltType.getSizeInBits() == 16);
7919
7920 if (IsFormat && !IsD16 && EltType.getSizeInBits() < 32) {
7921 DAG.getContext()->diagnose(DiagnosticInfoUnsupported(
7923 "unsupported sub-dword format buffer load", DL.getDebugLoc()));
7924 return DAG.getMergeValues({DAG.getPOISON(LoadVT), M->getOperand(0)}, DL);
7925 }
7926
7927 assert(M->getNumValues() == 2 || M->getNumValues() == 3);
7928 bool IsTFE = M->getNumValues() == 3;
7929
7930 unsigned Opc = IsFormat ? (IsTFE ? AMDGPUISD::BUFFER_LOAD_FORMAT_TFE
7931 : AMDGPUISD::BUFFER_LOAD_FORMAT)
7932 : IsTFE ? AMDGPUISD::BUFFER_LOAD_TFE
7933 : AMDGPUISD::BUFFER_LOAD;
7934
7935 if (IsD16) {
7936 return adjustLoadValueType(AMDGPUISD::BUFFER_LOAD_FORMAT_D16, M, DAG, Ops);
7937 }
7938
7939 // Handle BUFFER_LOAD_BYTE/UBYTE/SHORT/USHORT overloaded intrinsics
7940 if (!IsD16 && !LoadVT.isVector() && EltType.getSizeInBits() < 32)
7941 return handleByteShortBufferLoads(DAG, LoadVT, DL, Ops, M->getMemOperand(),
7942 IsTFE);
7943
7944 if (isTypeLegal(LoadVT)) {
7945 return getMemIntrinsicNode(Opc, DL, M->getVTList(), Ops, IntVT,
7946 M->getMemOperand(), DAG);
7947 }
7948
7949 EVT CastVT = getEquivalentMemType(*DAG.getContext(), LoadVT);
7950 SDVTList VTList = DAG.getVTList(CastVT, MVT::Other);
7951 SDValue MemNode = getMemIntrinsicNode(Opc, DL, VTList, Ops, CastVT,
7952 M->getMemOperand(), DAG);
7953 return DAG.getMergeValues(
7954 {DAG.getNode(ISD::BITCAST, DL, LoadVT, MemNode), MemNode.getValue(1)},
7955 DL);
7956}
7957
7959 SelectionDAG &DAG) {
7960 EVT VT = N->getValueType(0);
7961 SDValue Src = N->getOperand(1);
7962 SDLoc SL(N);
7963
7964 if (Src.getOpcode() == ISD::SETCC) {
7965 SDValue Op0 = Src.getOperand(0);
7966 SDValue Op1 = Src.getOperand(1);
7967 // Need to expand bfloat to float for comparison (setcc).
7968 if (Op0.getValueType() == MVT::bf16) {
7969 Op0 = DAG.getNode(ISD::FP_EXTEND, SL, MVT::f32, Op0);
7970 Op1 = DAG.getNode(ISD::FP_EXTEND, SL, MVT::f32, Op1);
7971 }
7972 // (ballot (ISD::SETCC ...)) -> (AMDGPUISD::SETCC ...)
7973 return DAG.getNode(AMDGPUISD::SETCC, SL, VT, Op0, Op1, Src.getOperand(2));
7974 }
7975 if (const ConstantSDNode *Arg = dyn_cast<ConstantSDNode>(Src)) {
7976 // (ballot 0) -> 0
7977 if (Arg->isZero())
7978 return DAG.getConstant(0, SL, VT);
7979
7980 // (ballot 1) -> EXEC/EXEC_LO
7981 if (Arg->isOne()) {
7982 Register Exec;
7983 if (VT.getScalarSizeInBits() == 32)
7984 Exec = AMDGPU::EXEC_LO;
7985 else if (VT.getScalarSizeInBits() == 64)
7986 Exec = AMDGPU::EXEC;
7987 else
7988 return SDValue();
7989
7990 return DAG.getCopyFromReg(DAG.getEntryNode(), SL, Exec, VT);
7991 }
7992 }
7993
7994 // (ballot (i1 $src)) -> (AMDGPUISD::SETCC (i32 (zext $src)) (i32 0)
7995 // ISD::SETNE)
7996 return DAG.getNode(
7997 AMDGPUISD::SETCC, SL, VT, DAG.getZExtOrTrunc(Src, SL, MVT::i32),
7998 DAG.getConstant(0, SL, MVT::i32), DAG.getCondCode(ISD::SETNE));
7999}
8000
8002 EVT VT);
8003
8005 SelectionDAG &DAG) {
8006 EVT VT = N->getValueType(0);
8007 unsigned ValSize = VT.getSizeInBits();
8008 unsigned IID = N->getConstantOperandVal(0);
8009 bool IsPermLane16 = IID == Intrinsic::amdgcn_permlane16 ||
8010 IID == Intrinsic::amdgcn_permlanex16;
8011 bool IsSetInactive = IID == Intrinsic::amdgcn_set_inactive ||
8012 IID == Intrinsic::amdgcn_set_inactive_chain_arg;
8013 bool IsPermlaneShuffle = IID == Intrinsic::amdgcn_permlane_bcast ||
8014 IID == Intrinsic::amdgcn_permlane_up ||
8015 IID == Intrinsic::amdgcn_permlane_down ||
8016 IID == Intrinsic::amdgcn_permlane_xor;
8017 SDLoc SL(N);
8018 MVT IntVT = MVT::getIntegerVT(ValSize);
8019 const GCNSubtarget *ST = TLI.getSubtarget();
8020
8021 unsigned SplitSize = 32;
8022 if (IID == Intrinsic::amdgcn_update_dpp && (ValSize % 64 == 0) &&
8023 ST->hasDPALU_DPP() &&
8024 AMDGPU::isLegalDPALU_DPPControl(*ST, N->getConstantOperandVal(3)))
8025 SplitSize = 64;
8026
8027 auto createLaneOp = [&DAG, &SL, N, IID](SDValue Src0, SDValue Src1,
8028 SDValue Src2, MVT ValT) -> SDValue {
8030 switch (IID) {
8031 case Intrinsic::amdgcn_permlane16:
8032 case Intrinsic::amdgcn_permlanex16:
8033 case Intrinsic::amdgcn_update_dpp:
8034 Operands.push_back(N->getOperand(6));
8035 Operands.push_back(N->getOperand(5));
8036 Operands.push_back(N->getOperand(4));
8037 [[fallthrough]];
8038 case Intrinsic::amdgcn_writelane:
8039 case Intrinsic::amdgcn_permlane_bcast:
8040 case Intrinsic::amdgcn_permlane_up:
8041 case Intrinsic::amdgcn_permlane_down:
8042 case Intrinsic::amdgcn_permlane_xor:
8043 Operands.push_back(Src2);
8044 [[fallthrough]];
8045 case Intrinsic::amdgcn_readlane:
8046 case Intrinsic::amdgcn_set_inactive:
8047 case Intrinsic::amdgcn_set_inactive_chain_arg:
8048 case Intrinsic::amdgcn_mov_dpp8:
8049 Operands.push_back(Src1);
8050 [[fallthrough]];
8051 case Intrinsic::amdgcn_readfirstlane:
8052 case Intrinsic::amdgcn_permlane64:
8053 Operands.push_back(Src0);
8054 break;
8055 default:
8056 llvm_unreachable("unhandled lane op");
8057 }
8058
8059 Operands.push_back(DAG.getTargetConstant(IID, SL, MVT::i32));
8060 std::reverse(Operands.begin(), Operands.end());
8061
8062 if (SDNode *GL = N->getGluedNode()) {
8063 assert(GL->getOpcode() == ISD::CONVERGENCECTRL_GLUE);
8064 GL = GL->getOperand(0).getNode();
8065 Operands.push_back(DAG.getNode(ISD::CONVERGENCECTRL_GLUE, SL, MVT::Glue,
8066 SDValue(GL, 0)));
8067 }
8068
8069 return DAG.getNode(ISD::INTRINSIC_WO_CHAIN, SL, ValT, Operands);
8070 };
8071
8072 SDValue Src0 = N->getOperand(1);
8073 SDValue Src1, Src2;
8074 if (IID == Intrinsic::amdgcn_readlane || IID == Intrinsic::amdgcn_writelane ||
8075 IID == Intrinsic::amdgcn_mov_dpp8 ||
8076 IID == Intrinsic::amdgcn_update_dpp || IsSetInactive || IsPermLane16 ||
8077 IsPermlaneShuffle) {
8078 Src1 = N->getOperand(2);
8079 if (IID == Intrinsic::amdgcn_writelane ||
8080 IID == Intrinsic::amdgcn_update_dpp || IsPermLane16 ||
8081 IsPermlaneShuffle)
8082 Src2 = N->getOperand(3);
8083 }
8084
8085 if (ValSize == SplitSize) {
8086 // Already legal
8087 return SDValue();
8088 }
8089
8090 if (ValSize < 32) {
8091 bool IsFloat = VT.isFloatingPoint();
8092 Src0 = DAG.getAnyExtOrTrunc(IsFloat ? DAG.getBitcast(IntVT, Src0) : Src0,
8093 SL, MVT::i32);
8094
8095 if (IID == Intrinsic::amdgcn_update_dpp || IsSetInactive || IsPermLane16) {
8096 Src1 = DAG.getAnyExtOrTrunc(IsFloat ? DAG.getBitcast(IntVT, Src1) : Src1,
8097 SL, MVT::i32);
8098 }
8099
8100 if (IID == Intrinsic::amdgcn_writelane) {
8101 Src2 = DAG.getAnyExtOrTrunc(IsFloat ? DAG.getBitcast(IntVT, Src2) : Src2,
8102 SL, MVT::i32);
8103 }
8104
8105 SDValue LaneOp = createLaneOp(Src0, Src1, Src2, MVT::i32);
8106 SDValue Trunc = DAG.getAnyExtOrTrunc(LaneOp, SL, IntVT);
8107 return IsFloat ? DAG.getBitcast(VT, Trunc) : Trunc;
8108 }
8109
8110 if (ValSize % SplitSize != 0)
8111 return SDValue();
8112
8113 auto unrollLaneOp = [&DAG, &SL](SDNode *N) -> SDValue {
8114 EVT VT = N->getValueType(0);
8115 unsigned NE = VT.getVectorNumElements();
8116 EVT EltVT = VT.getVectorElementType();
8118 unsigned NumOperands = N->getNumOperands();
8119 SmallVector<SDValue, 4> Operands(NumOperands);
8120 SDNode *GL = N->getGluedNode();
8121
8122 // only handle convergencectrl_glue
8124
8125 for (unsigned i = 0; i != NE; ++i) {
8126 for (unsigned j = 0, e = GL ? NumOperands - 1 : NumOperands; j != e;
8127 ++j) {
8128 SDValue Operand = N->getOperand(j);
8129 EVT OperandVT = Operand.getValueType();
8130 if (OperandVT.isVector()) {
8131 // A vector operand; extract a single element.
8132 EVT OperandEltVT = OperandVT.getVectorElementType();
8133 Operands[j] = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, SL, OperandEltVT,
8134 Operand, DAG.getVectorIdxConstant(i, SL));
8135 } else {
8136 // A scalar operand; just use it as is.
8137 Operands[j] = Operand;
8138 }
8139 }
8140
8141 if (GL)
8142 Operands[NumOperands - 1] =
8143 DAG.getNode(ISD::CONVERGENCECTRL_GLUE, SL, MVT::Glue,
8144 SDValue(GL->getOperand(0).getNode(), 0));
8145
8146 Scalars.push_back(DAG.getNode(N->getOpcode(), SL, EltVT, Operands));
8147 }
8148
8149 EVT VecVT = EVT::getVectorVT(*DAG.getContext(), EltVT, NE);
8150 return DAG.getBuildVector(VecVT, SL, Scalars);
8151 };
8152
8153 if (VT.isVector()) {
8154 switch (MVT::SimpleValueType EltTy =
8156 case MVT::i32:
8157 case MVT::f32:
8158 if (SplitSize == 32) {
8159 SDValue LaneOp = createLaneOp(Src0, Src1, Src2, VT.getSimpleVT());
8160 return unrollLaneOp(LaneOp.getNode());
8161 }
8162 [[fallthrough]];
8163 case MVT::i16:
8164 case MVT::f16:
8165 case MVT::bf16: {
8166 unsigned SubVecNumElt =
8167 SplitSize / VT.getVectorElementType().getSizeInBits();
8168 MVT SubVecVT = MVT::getVectorVT(EltTy, SubVecNumElt);
8170 SDValue Src0SubVec, Src1SubVec, Src2SubVec;
8171 for (unsigned i = 0, EltIdx = 0; i < ValSize / SplitSize; i++) {
8172 Src0SubVec = DAG.getNode(ISD::EXTRACT_SUBVECTOR, SL, SubVecVT, Src0,
8173 DAG.getConstant(EltIdx, SL, MVT::i32));
8174
8175 if (IID == Intrinsic::amdgcn_update_dpp || IsSetInactive ||
8176 IsPermLane16) {
8177 Src1SubVec = DAG.getNode(ISD::EXTRACT_SUBVECTOR, SL, SubVecVT, Src1,
8178 DAG.getConstant(EltIdx, SL, MVT::i32));
8179
8180 Pieces.push_back(
8181 createLaneOp(Src0SubVec, Src1SubVec, Src2, SubVecVT));
8182 } else if (IID == Intrinsic::amdgcn_writelane) {
8183 Src2SubVec = DAG.getNode(ISD::EXTRACT_SUBVECTOR, SL, SubVecVT, Src2,
8184 DAG.getConstant(EltIdx, SL, MVT::i32));
8185 Pieces.push_back(
8186 createLaneOp(Src0SubVec, Src1, Src2SubVec, SubVecVT));
8187 } else {
8188 Pieces.push_back(createLaneOp(Src0SubVec, Src1, Src2, SubVecVT));
8189 }
8190
8191 EltIdx += SubVecNumElt;
8192 }
8193 return DAG.getNode(ISD::CONCAT_VECTORS, SL, VT, Pieces);
8194 }
8195 default:
8196 // Handle all other cases by bitcasting to i32 vectors
8197 break;
8198 }
8199 }
8200
8201 MVT VecVT =
8202 MVT::getVectorVT(MVT::getIntegerVT(SplitSize), ValSize / SplitSize);
8203 Src0 = DAG.getBitcast(VecVT, Src0);
8204
8205 if (IID == Intrinsic::amdgcn_update_dpp || IsSetInactive || IsPermLane16)
8206 Src1 = DAG.getBitcast(VecVT, Src1);
8207
8208 if (IID == Intrinsic::amdgcn_writelane)
8209 Src2 = DAG.getBitcast(VecVT, Src2);
8210
8211 SDValue LaneOp = createLaneOp(Src0, Src1, Src2, VecVT);
8212 SDValue UnrolledLaneOp = unrollLaneOp(LaneOp.getNode());
8213 return DAG.getBitcast(VT, UnrolledLaneOp);
8214}
8215
8217 SelectionDAG &DAG) {
8218 EVT VT = N->getValueType(0);
8219
8220 if (VT.getSizeInBits() != 32)
8221 return SDValue();
8222
8223 SDLoc SL(N);
8224
8225 SDValue Value = N->getOperand(1);
8226 SDValue Index = N->getOperand(2);
8227
8228 // ds_bpermute requires index to be multiplied by 4
8229 SDValue ShiftAmount = DAG.getShiftAmountConstant(2, MVT::i32, SL);
8230 SDValue ShiftedIndex =
8231 DAG.getNode(ISD::SHL, SL, Index.getValueType(), Index, ShiftAmount);
8232
8233 // Intrinsics will require i32 to operate on
8234 SDValue ValueI32 = DAG.getBitcast(MVT::i32, Value);
8235
8236 auto MakeIntrinsic = [&DAG, &SL](unsigned IID, MVT RetVT,
8237 SmallVector<SDValue> IntrinArgs) -> SDValue {
8239 Operands[0] = DAG.getTargetConstant(IID, SL, MVT::i32);
8240 Operands.append(IntrinArgs);
8241 return DAG.getNode(ISD::INTRINSIC_WO_CHAIN, SL, RetVT, Operands);
8242 };
8243
8244 // If we can bpermute across the whole wave, then just do that
8246 SDValue BPermute = MakeIntrinsic(Intrinsic::amdgcn_ds_bpermute, MVT::i32,
8247 {ShiftedIndex, ValueI32});
8248 return DAG.getBitcast(VT, BPermute);
8249 }
8250
8251 assert(TLI.getSubtarget()->isWave64());
8252
8253 // Otherwise, we need to make use of whole wave mode
8254 SDValue PoisonVal = DAG.getPOISON(ValueI32->getValueType(0));
8255
8256 // Set inactive lanes to poison
8257 SDValue WWMValue = MakeIntrinsic(Intrinsic::amdgcn_set_inactive, MVT::i32,
8258 {ValueI32, PoisonVal});
8259 SDValue WWMIndex = MakeIntrinsic(Intrinsic::amdgcn_set_inactive, MVT::i32,
8260 {ShiftedIndex, PoisonVal});
8261
8262 SDValue Swapped =
8263 MakeIntrinsic(Intrinsic::amdgcn_permlane64, MVT::i32, {WWMValue});
8264
8265 // Get permutation of each half, then we'll select which one to use
8266 SDValue BPermSameHalf = MakeIntrinsic(Intrinsic::amdgcn_ds_bpermute, MVT::i32,
8267 {WWMIndex, WWMValue});
8268 SDValue BPermOtherHalf = MakeIntrinsic(Intrinsic::amdgcn_ds_bpermute,
8269 MVT::i32, {WWMIndex, Swapped});
8270 SDValue BPermOtherHalfWWM =
8271 MakeIntrinsic(Intrinsic::amdgcn_wwm, MVT::i32, {BPermOtherHalf});
8272
8273 // Select which side to take the permute from
8274 SDValue ThreadIDMask = DAG.getAllOnesConstant(SL, MVT::i32);
8275 // We can get away with only using mbcnt_lo here since we're only
8276 // trying to detect which side of 32 each lane is on, and mbcnt_lo
8277 // returns 32 for lanes 32-63.
8278 SDValue ThreadID =
8279 MakeIntrinsic(Intrinsic::amdgcn_mbcnt_lo, MVT::i32,
8280 {ThreadIDMask, DAG.getTargetConstant(0, SL, MVT::i32)});
8281
8282 SDValue SameOrOtherHalf =
8283 DAG.getNode(ISD::AND, SL, MVT::i32,
8284 DAG.getNode(ISD::XOR, SL, MVT::i32, ThreadID, Index),
8285 DAG.getTargetConstant(32, SL, MVT::i32));
8286 SDValue UseSameHalf =
8287 DAG.getSetCC(SL, MVT::i1, SameOrOtherHalf,
8288 DAG.getConstant(0, SL, MVT::i32), ISD::SETEQ);
8289 SDValue Result = DAG.getSelect(SL, MVT::i32, UseSameHalf, BPermSameHalf,
8290 BPermOtherHalfWWM);
8291 return DAG.getBitcast(VT, Result);
8292}
8293
8296 SelectionDAG &DAG) const {
8297 switch (N->getOpcode()) {
8299 if (SDValue Res = lowerINSERT_VECTOR_ELT(SDValue(N, 0), DAG))
8300 Results.push_back(Res);
8301 return;
8302 }
8304 if (SDValue Res = lowerEXTRACT_VECTOR_ELT(SDValue(N, 0), DAG))
8305 Results.push_back(Res);
8306 return;
8307 }
8309 if (SDValue Res = LowerCONVERT_TO_ARBITRARY_FP(SDValue(N, 0), DAG))
8310 Results.push_back(Res);
8311 return;
8312 }
8314 unsigned IID = N->getConstantOperandVal(0);
8315 switch (IID) {
8316 case Intrinsic::amdgcn_wave_reduce_min:
8317 case Intrinsic::amdgcn_wave_reduce_umin:
8318 case Intrinsic::amdgcn_wave_reduce_max:
8319 case Intrinsic::amdgcn_wave_reduce_umax:
8320 case Intrinsic::amdgcn_wave_reduce_add:
8321 case Intrinsic::amdgcn_wave_reduce_sub:
8322 case Intrinsic::amdgcn_wave_reduce_and:
8323 case Intrinsic::amdgcn_wave_reduce_or:
8324 case Intrinsic::amdgcn_wave_reduce_xor: {
8325 EVT VT = N->getValueType(0);
8326 if (isTypeLegal(VT))
8327 return;
8328 SDLoc SL(N);
8329 bool NeedsSignExt = IID == Intrinsic::amdgcn_wave_reduce_min ||
8330 IID == Intrinsic::amdgcn_wave_reduce_max ||
8331 IID == Intrinsic::amdgcn_wave_reduce_add ||
8332 IID == Intrinsic::amdgcn_wave_reduce_sub;
8333 unsigned ExtOpc = NeedsSignExt ? ISD::SIGN_EXTEND : ISD::ZERO_EXTEND;
8334 SDValue ExtSrc = DAG.getNode(ExtOpc, SL, MVT::i32, N->getOperand(1));
8335 SDValue Result = DAG.getNode(ISD::INTRINSIC_WO_CHAIN, SL, MVT::i32,
8336 N->getOperand(0), ExtSrc, N->getOperand(2));
8337 Results.push_back(DAG.getNode(ISD::TRUNCATE, SL, VT, Result));
8338 return;
8339 }
8340 case Intrinsic::amdgcn_make_buffer_rsrc:
8341 Results.push_back(lowerPointerAsRsrcIntrin(N, DAG));
8342 return;
8343 case Intrinsic::amdgcn_cvt_pkrtz: {
8344 SDValue Src0 = N->getOperand(1);
8345 SDValue Src1 = N->getOperand(2);
8346 SDLoc SL(N);
8347 SDValue Cvt =
8348 DAG.getNode(AMDGPUISD::CVT_PKRTZ_F16_F32, SL, MVT::i32, Src0, Src1);
8349 Results.push_back(DAG.getNode(ISD::BITCAST, SL, MVT::v2f16, Cvt));
8350 return;
8351 }
8352 case Intrinsic::amdgcn_cvt_pknorm_i16:
8353 case Intrinsic::amdgcn_cvt_pknorm_u16:
8354 case Intrinsic::amdgcn_cvt_pk_i16:
8355 case Intrinsic::amdgcn_cvt_pk_u16: {
8356 SDValue Src0 = N->getOperand(1);
8357 SDValue Src1 = N->getOperand(2);
8358 SDLoc SL(N);
8359 unsigned Opcode;
8360
8361 if (IID == Intrinsic::amdgcn_cvt_pknorm_i16)
8362 Opcode = AMDGPUISD::CVT_PKNORM_I16_F32;
8363 else if (IID == Intrinsic::amdgcn_cvt_pknorm_u16)
8364 Opcode = AMDGPUISD::CVT_PKNORM_U16_F32;
8365 else if (IID == Intrinsic::amdgcn_cvt_pk_i16)
8366 Opcode = AMDGPUISD::CVT_PK_I16_I32;
8367 else
8368 Opcode = AMDGPUISD::CVT_PK_U16_U32;
8369
8370 EVT VT = N->getValueType(0);
8371 if (isTypeLegal(VT))
8372 Results.push_back(DAG.getNode(Opcode, SL, VT, Src0, Src1));
8373 else {
8374 SDValue Cvt = DAG.getNode(Opcode, SL, MVT::i32, Src0, Src1);
8375 Results.push_back(DAG.getNode(ISD::BITCAST, SL, MVT::v2i16, Cvt));
8376 }
8377 return;
8378 }
8379 case Intrinsic::amdgcn_s_buffer_load: {
8380 // Lower llvm.amdgcn.s.buffer.load.(i8, u8) intrinsics. First, we generate
8381 // s_buffer_load_u8 for signed and unsigned load instructions. Next, DAG
8382 // combiner tries to merge the s_buffer_load_u8 with a sext instruction
8383 // (performSignExtendInRegCombine()) and it replaces s_buffer_load_u8 with
8384 // s_buffer_load_i8.
8385 if (!Subtarget->hasScalarSubwordLoads())
8386 return;
8387 SDValue Op = SDValue(N, 0);
8388 SDValue Rsrc = Op.getOperand(1);
8389 SDValue Offset = Op.getOperand(2);
8390 SDValue CachePolicy = Op.getOperand(3);
8391 EVT VT = Op.getValueType();
8392 assert(VT == MVT::i8 && "Expected 8-bit s_buffer_load intrinsics.\n");
8393 SDLoc DL(Op);
8395 const DataLayout &DataLayout = DAG.getDataLayout();
8396 Align Alignment =
8402 VT.getStoreSize(), Alignment);
8403 SDValue LoadVal;
8404 if (!Offset->isDivergent()) {
8405 SDValue Ops[] = {DAG.getEntryNode(), // Chain
8406 Rsrc, // source register
8407 Offset, CachePolicy};
8408 SDValue BufferLoad = DAG.getMemIntrinsicNode(
8409 AMDGPUISD::SBUFFER_LOAD_UBYTE, DL,
8410 DAG.getVTList(MVT::i32, MVT::Other), Ops, VT, MMO);
8411 LoadVal = DAG.getNode(ISD::TRUNCATE, DL, VT, BufferLoad);
8412 } else {
8413 SDValue Ops[] = {
8414 DAG.getEntryNode(), // Chain
8415 Rsrc, // rsrc
8416 DAG.getConstant(0, DL, MVT::i32), // vindex
8417 {}, // voffset
8418 {}, // soffset
8419 {}, // offset
8420 CachePolicy, // cachepolicy
8421 DAG.getTargetConstant(0, DL, MVT::i1), // idxen
8422 };
8423 setBufferOffsets(Offset, DAG, &Ops[3], Align(4));
8424 LoadVal = handleByteShortBufferLoads(DAG, VT, DL, Ops, MMO);
8425 }
8426 Results.push_back(LoadVal);
8427 return;
8428 }
8429 case Intrinsic::amdgcn_dead: {
8430 for (unsigned I = 0, E = N->getNumValues(); I < E; ++I)
8431 Results.push_back(DAG.getPOISON(N->getValueType(I)));
8432 return;
8433 }
8434 }
8435 break;
8436 }
8438 if (SDValue Res = LowerINTRINSIC_W_CHAIN(SDValue(N, 0), DAG)) {
8439 if (Res.getOpcode() == ISD::MERGE_VALUES) {
8440 // FIXME: Hacky
8441 for (unsigned I = 0; I < Res.getNumOperands(); I++) {
8442 Results.push_back(Res.getOperand(I));
8443 }
8444 } else {
8445 Results.push_back(Res);
8446 Results.push_back(Res.getValue(1));
8447 }
8448 return;
8449 }
8450
8451 break;
8452 }
8453 case ISD::SELECT: {
8454 SDLoc SL(N);
8455 EVT VT = N->getValueType(0);
8456 EVT NewVT = getEquivalentMemType(*DAG.getContext(), VT);
8457 SDValue LHS = DAG.getNode(ISD::BITCAST, SL, NewVT, N->getOperand(1));
8458 SDValue RHS = DAG.getNode(ISD::BITCAST, SL, NewVT, N->getOperand(2));
8459
8460 EVT SelectVT = NewVT;
8461 if (NewVT.bitsLT(MVT::i32)) {
8462 LHS = DAG.getNode(ISD::ANY_EXTEND, SL, MVT::i32, LHS);
8463 RHS = DAG.getNode(ISD::ANY_EXTEND, SL, MVT::i32, RHS);
8464 SelectVT = MVT::i32;
8465 }
8466
8467 SDValue NewSelect =
8468 DAG.getNode(ISD::SELECT, SL, SelectVT, N->getOperand(0), LHS, RHS);
8469
8470 if (NewVT != SelectVT)
8471 NewSelect = DAG.getNode(ISD::TRUNCATE, SL, NewVT, NewSelect);
8472 Results.push_back(DAG.getNode(ISD::BITCAST, SL, VT, NewSelect));
8473 return;
8474 }
8475 case ISD::FNEG: {
8476 if (N->getValueType(0) != MVT::v2f16)
8477 break;
8478
8479 SDLoc SL(N);
8480 SDValue BC = DAG.getNode(ISD::BITCAST, SL, MVT::i32, N->getOperand(0));
8481
8482 SDValue Op = DAG.getNode(ISD::XOR, SL, MVT::i32, BC,
8483 DAG.getConstant(0x80008000, SL, MVT::i32));
8484 Results.push_back(DAG.getNode(ISD::BITCAST, SL, MVT::v2f16, Op));
8485 return;
8486 }
8487 case ISD::FABS: {
8488 if (N->getValueType(0) != MVT::v2f16)
8489 break;
8490
8491 SDLoc SL(N);
8492 SDValue BC = DAG.getNode(ISD::BITCAST, SL, MVT::i32, N->getOperand(0));
8493
8494 SDValue Op = DAG.getNode(ISD::AND, SL, MVT::i32, BC,
8495 DAG.getConstant(0x7fff7fff, SL, MVT::i32));
8496 Results.push_back(DAG.getNode(ISD::BITCAST, SL, MVT::v2f16, Op));
8497 return;
8498 }
8499 case ISD::FSQRT: {
8500 if (N->getValueType(0) != MVT::f16)
8501 break;
8502 Results.push_back(lowerFSQRTF16(SDValue(N, 0), DAG));
8503 break;
8504 }
8505 default:
8507 break;
8508 }
8509}
8510
8511/// Helper function for LowerBRCOND
8512static SDNode *findUser(SDValue Value, unsigned Opcode) {
8513
8514 for (SDUse &U : Value->uses()) {
8515 if (U.get() != Value)
8516 continue;
8517
8518 if (U.getUser()->getOpcode() == Opcode)
8519 return U.getUser();
8520 }
8521 return nullptr;
8522}
8523
8524unsigned SITargetLowering::isCFIntrinsic(const SDNode *Intr) const {
8525 if (Intr->getOpcode() == ISD::INTRINSIC_W_CHAIN) {
8526 switch (Intr->getConstantOperandVal(1)) {
8527 case Intrinsic::amdgcn_if:
8528 return AMDGPUISD::IF;
8529 case Intrinsic::amdgcn_else:
8530 return AMDGPUISD::ELSE;
8531 case Intrinsic::amdgcn_loop:
8532 return AMDGPUISD::LOOP;
8533 case Intrinsic::amdgcn_end_cf:
8534 llvm_unreachable("should not occur");
8535 default:
8536 return 0;
8537 }
8538 }
8539
8540 // break, if_break, else_break are all only used as inputs to loop, not
8541 // directly as branch conditions.
8542 return 0;
8543}
8544
8551
8553 if (Subtarget->isAmdPalOS() || Subtarget->isMesa3DOS())
8554 return false;
8555
8556 // FIXME: Either avoid relying on address space here or change the default
8557 // address space for functions to avoid the explicit check.
8558 return (GV->getValueType()->isFunctionTy() ||
8561}
8562
8564 return !shouldEmitFixup(GV) && !shouldEmitGOTReloc(GV);
8565}
8566
8568 if (!GV->hasExternalLinkage())
8569 return true;
8570
8571 // With object linking, external LDS declarations need relocations so the
8572 // linker can assign their offsets.
8574 if (const auto *GVar = dyn_cast<GlobalVariable>(GV)) {
8575 if (GVar->getAddressSpace() == AMDGPUAS::LOCAL_ADDRESS) {
8576 assert(GVar->isDeclaration() && "AS3 GVs should be declaration here "
8577 "when object linking is enabled");
8578 return false;
8579 }
8580 }
8581 }
8582
8583 const auto OS = getTargetMachine().getTargetTriple().getOS();
8584 return OS == Triple::AMDHSA || OS == Triple::AMDPAL;
8585}
8586
8587/// This transforms the control flow intrinsics to get the branch destination as
8588/// last parameter, also switches branch target with BR if the need arise
8589SDValue SITargetLowering::LowerBRCOND(SDValue BRCOND, SelectionDAG &DAG) const {
8590 SDLoc DL(BRCOND);
8591
8592 SDNode *Intr = BRCOND.getOperand(1).getNode();
8593 SDValue Target = BRCOND.getOperand(2);
8594 SDNode *BR = nullptr;
8595 SDNode *SetCC = nullptr;
8596
8597 switch (Intr->getOpcode()) {
8598 case ISD::SETCC: {
8599 // As long as we negate the condition everything is fine
8600 SetCC = Intr;
8601 Intr = SetCC->getOperand(0).getNode();
8602 break;
8603 }
8604 case ISD::XOR: {
8605 // Similar to SETCC, if we have (xor c, -1), we will be fine.
8606 SDValue LHS = Intr->getOperand(0);
8607 SDValue RHS = Intr->getOperand(1);
8608 if (auto *C = dyn_cast<ConstantSDNode>(RHS); C && C->getZExtValue()) {
8609 Intr = LHS.getNode();
8610 break;
8611 }
8612 [[fallthrough]];
8613 }
8614 default: {
8615 // Get the target from BR if we don't negate the condition
8616 BR = findUser(BRCOND, ISD::BR);
8617 assert(BR && "brcond missing unconditional branch user");
8618 Target = BR->getOperand(1);
8619 }
8620 }
8621
8622 unsigned CFNode = isCFIntrinsic(Intr);
8623 if (CFNode == 0) {
8624 // This is a uniform branch so we don't need to legalize.
8625 return BRCOND;
8626 }
8627
8628 bool HaveChain = Intr->getOpcode() == ISD::INTRINSIC_VOID ||
8630
8631 assert(!SetCC ||
8632 (SetCC->getConstantOperandVal(1) == 1 &&
8633 cast<CondCodeSDNode>(SetCC->getOperand(2).getNode())->get() ==
8634 ISD::SETNE));
8635
8636 // operands of the new intrinsic call
8638 if (HaveChain)
8639 Ops.push_back(BRCOND.getOperand(0));
8640
8641 Ops.append(Intr->op_begin() + (HaveChain ? 2 : 1), Intr->op_end());
8642 Ops.push_back(Target);
8643
8644 ArrayRef<EVT> Res(Intr->value_begin() + 1, Intr->value_end());
8645
8646 // build the new intrinsic call
8647 SDNode *Result = DAG.getNode(CFNode, DL, DAG.getVTList(Res), Ops).getNode();
8648
8649 if (!HaveChain) {
8650 SDValue Ops[] = {SDValue(Result, 0), BRCOND.getOperand(0)};
8651
8653 }
8654
8655 if (BR) {
8656 // Give the branch instruction our target
8657 SDValue Ops[] = {BR->getOperand(0), BRCOND.getOperand(2)};
8658 SDValue NewBR = DAG.getNode(ISD::BR, DL, BR->getVTList(), Ops);
8659 DAG.ReplaceAllUsesWith(BR, NewBR.getNode());
8660 }
8661
8662 SDValue Chain = SDValue(Result, Result->getNumValues() - 1);
8663
8664 // Copy the intrinsic results to registers
8665 for (unsigned i = 1, e = Intr->getNumValues() - 1; i != e; ++i) {
8666 SDNode *CopyToReg = findUser(SDValue(Intr, i), ISD::CopyToReg);
8667 if (!CopyToReg)
8668 continue;
8669
8670 Chain = DAG.getCopyToReg(Chain, DL, CopyToReg->getOperand(1),
8671 SDValue(Result, i - 1), SDValue());
8672
8673 DAG.ReplaceAllUsesWith(SDValue(CopyToReg, 0), CopyToReg->getOperand(0));
8674 }
8675
8676 // Remove the old intrinsic from the chain
8677 DAG.ReplaceAllUsesOfValueWith(SDValue(Intr, Intr->getNumValues() - 1),
8678 Intr->getOperand(0));
8679
8680 return Chain;
8681}
8682
8683SDValue SITargetLowering::LowerRETURNADDR(SDValue Op, SelectionDAG &DAG) const {
8684 MVT VT = Op.getSimpleValueType();
8685 SDLoc DL(Op);
8686 // Checking the depth
8687 if (Op.getConstantOperandVal(0) != 0)
8688 return DAG.getConstant(0, DL, VT);
8689
8691 const SIMachineFunctionInfo *Info = MF.getInfo<SIMachineFunctionInfo>();
8692 // Check for kernel and shader functions
8693 if (Info->isEntryFunction())
8694 return DAG.getConstant(0, DL, VT);
8695
8696 MachineFrameInfo &MFI = MF.getFrameInfo();
8697 // There is a call to @llvm.returnaddress in this function
8698 MFI.setReturnAddressIsTaken(true);
8699
8700 const SIRegisterInfo *TRI = getSubtarget()->getRegisterInfo();
8701 // Get the return address reg and mark it as an implicit live-in
8702 Register Reg = MF.addLiveIn(TRI->getReturnAddressReg(MF),
8703 getRegClassFor(VT, Op.getNode()->isDivergent()));
8704
8705 return DAG.getCopyFromReg(DAG.getEntryNode(), DL, Reg, VT);
8706}
8707
8708SDValue SITargetLowering::LowerSPONENTRY(SDValue Op, SelectionDAG &DAG) const {
8710 SIMachineFunctionInfo *MFI = MF.getInfo<SIMachineFunctionInfo>();
8711
8712 // For functions that set up their own stack, select the GET_STACK_BASE
8713 // pseudo.
8714 if (MFI->isBottomOfStack())
8715 return Op;
8716
8717 // For everything else, create a dummy stack object.
8718 int FI = MF.getFrameInfo().CreateFixedObject(1, 0, /*IsImmutable=*/false);
8719 return DAG.