@@ -2255,28 +2255,79 @@ static MachineInstr *verifyCFIntrinsic(MachineInstr &MI,
2255
2255
return &UseMI;
2256
2256
}
2257
2257
2258
- Register AMDGPULegalizerInfo::getLiveInRegister (MachineRegisterInfo &MRI,
2259
- Register Reg, LLT Ty) const {
2260
- Register LiveIn = MRI.getLiveInVirtReg (Reg);
2261
- if (LiveIn)
2258
+ Register AMDGPULegalizerInfo::insertLiveInCopy (MachineIRBuilder &B,
2259
+ MachineRegisterInfo &MRI,
2260
+ Register LiveIn,
2261
+ Register PhyReg) const {
2262
+ assert (PhyReg.isPhysical () && " Physical register expected" );
2263
+
2264
+ // Insert the live-in copy, if required, by defining destination virtual
2265
+ // register.
2266
+ // FIXME: It seems EmitLiveInCopies isn't called anywhere?
2267
+ if (!MRI.getVRegDef (LiveIn)) {
2268
+ // FIXME: Should have scoped insert pt
2269
+ MachineBasicBlock &OrigInsBB = B.getMBB ();
2270
+ auto OrigInsPt = B.getInsertPt ();
2271
+
2272
+ MachineBasicBlock &EntryMBB = B.getMF ().front ();
2273
+ EntryMBB.addLiveIn (PhyReg);
2274
+ B.setInsertPt (EntryMBB, EntryMBB.begin ());
2275
+ B.buildCopy (LiveIn, PhyReg);
2276
+
2277
+ B.setInsertPt (OrigInsBB, OrigInsPt);
2278
+ }
2279
+
2280
+ return LiveIn;
2281
+ }
2282
+
2283
+ Register AMDGPULegalizerInfo::getLiveInRegister (MachineIRBuilder &B,
2284
+ MachineRegisterInfo &MRI,
2285
+ Register PhyReg, LLT Ty,
2286
+ bool InsertLiveInCopy) const {
2287
+ assert (PhyReg.isPhysical () && " Physical register expected" );
2288
+
2289
+ // Get or create virtual live-in regester
2290
+ Register LiveIn = MRI.getLiveInVirtReg (PhyReg);
2291
+ if (!LiveIn) {
2292
+ LiveIn = MRI.createGenericVirtualRegister (Ty);
2293
+ MRI.addLiveIn (PhyReg, LiveIn);
2294
+ }
2295
+
2296
+ // When the actual true copy required is from virtual register to physical
2297
+ // register (to be inserted later), live-in copy insertion from physical
2298
+ // to register virtual register is not required
2299
+ if (!InsertLiveInCopy)
2262
2300
return LiveIn;
2263
2301
2264
- Register NewReg = MRI.createGenericVirtualRegister (Ty);
2265
- MRI.addLiveIn (Reg, NewReg);
2266
- return NewReg;
2302
+ return insertLiveInCopy (B, MRI, LiveIn, PhyReg);
2303
+ }
2304
+
2305
+ const ArgDescriptor *AMDGPULegalizerInfo::getArgDescriptor (
2306
+ MachineIRBuilder &B, AMDGPUFunctionArgInfo::PreloadedValue ArgType) const {
2307
+ const SIMachineFunctionInfo *MFI = B.getMF ().getInfo <SIMachineFunctionInfo>();
2308
+ const ArgDescriptor *Arg;
2309
+ const TargetRegisterClass *RC;
2310
+ std::tie (Arg, RC) = MFI->getPreloadedValue (ArgType);
2311
+ if (!Arg) {
2312
+ LLVM_DEBUG (dbgs () << " Required arg register missing\n " );
2313
+ return nullptr ;
2314
+ }
2315
+ return Arg;
2267
2316
}
2268
2317
2269
2318
bool AMDGPULegalizerInfo::loadInputValue (Register DstReg, MachineIRBuilder &B,
2270
2319
const ArgDescriptor *Arg) const {
2271
2320
if (!Arg->isRegister () || !Arg->getRegister ().isValid ())
2272
2321
return false ; // TODO: Handle these
2273
2322
2274
- assert (Arg->getRegister ().isPhysical ());
2323
+ Register SrcReg = Arg->getRegister ();
2324
+ assert (SrcReg.isPhysical () && " Physical register expected" );
2325
+ assert (DstReg.isVirtual () && " Virtual register expected" );
2275
2326
2276
2327
MachineRegisterInfo &MRI = *B.getMRI ();
2277
2328
2278
2329
LLT Ty = MRI.getType (DstReg);
2279
- Register LiveIn = getLiveInRegister (MRI, Arg-> getRegister () , Ty);
2330
+ Register LiveIn = getLiveInRegister (B, MRI, SrcReg , Ty);
2280
2331
2281
2332
if (Arg->isMasked ()) {
2282
2333
// TODO: Should we try to emit this once in the entry block?
@@ -2292,50 +2343,27 @@ bool AMDGPULegalizerInfo::loadInputValue(Register DstReg, MachineIRBuilder &B,
2292
2343
}
2293
2344
2294
2345
B.buildAnd (DstReg, AndMaskSrc, B.buildConstant (S32, Mask >> Shift));
2295
- } else
2346
+ } else {
2296
2347
B.buildCopy (DstReg, LiveIn);
2297
-
2298
- // Insert the argument copy if it doens't already exist.
2299
- // FIXME: It seems EmitLiveInCopies isn't called anywhere?
2300
- if (!MRI.getVRegDef (LiveIn)) {
2301
- // FIXME: Should have scoped insert pt
2302
- MachineBasicBlock &OrigInsBB = B.getMBB ();
2303
- auto OrigInsPt = B.getInsertPt ();
2304
-
2305
- MachineBasicBlock &EntryMBB = B.getMF ().front ();
2306
- EntryMBB.addLiveIn (Arg->getRegister ());
2307
- B.setInsertPt (EntryMBB, EntryMBB.begin ());
2308
- B.buildCopy (LiveIn, Arg->getRegister ());
2309
-
2310
- B.setInsertPt (OrigInsBB, OrigInsPt);
2311
2348
}
2312
2349
2313
2350
return true ;
2314
2351
}
2315
2352
2316
2353
bool AMDGPULegalizerInfo::legalizePreloadedArgIntrin (
2317
- MachineInstr &MI,
2318
- MachineRegisterInfo &MRI,
2319
- MachineIRBuilder &B,
2320
- AMDGPUFunctionArgInfo::PreloadedValue ArgType) const {
2354
+ MachineInstr &MI, MachineRegisterInfo &MRI, MachineIRBuilder &B,
2355
+ AMDGPUFunctionArgInfo::PreloadedValue ArgType) const {
2321
2356
B.setInstr (MI);
2322
2357
2323
- const SIMachineFunctionInfo *MFI = B.getMF ().getInfo <SIMachineFunctionInfo>();
2324
-
2325
- const ArgDescriptor *Arg;
2326
- const TargetRegisterClass *RC;
2327
- std::tie (Arg, RC) = MFI->getPreloadedValue (ArgType);
2328
- if (!Arg) {
2329
- LLVM_DEBUG (dbgs () << " Required arg register missing\n " );
2358
+ const ArgDescriptor *Arg = getArgDescriptor (B, ArgType);
2359
+ if (!Arg)
2330
2360
return false ;
2331
- }
2332
2361
2333
- if (loadInputValue (MI.getOperand (0 ).getReg (), B, Arg)) {
2334
- MI.eraseFromParent ();
2335
- return true ;
2336
- }
2362
+ if (!loadInputValue (MI.getOperand (0 ).getReg (), B, Arg))
2363
+ return false ;
2337
2364
2338
- return false ;
2365
+ MI.eraseFromParent ();
2366
+ return true ;
2339
2367
}
2340
2368
2341
2369
bool AMDGPULegalizerInfo::legalizeFDIV (MachineInstr &MI,
@@ -3558,6 +3586,61 @@ bool AMDGPULegalizerInfo::legalizeSBufferLoad(
3558
3586
return true ;
3559
3587
}
3560
3588
3589
+ bool AMDGPULegalizerInfo::legalizeTrapIntrinsic (MachineInstr &MI,
3590
+ MachineRegisterInfo &MRI,
3591
+ MachineIRBuilder &B) const {
3592
+ B.setInstr (MI);
3593
+
3594
+ // Is non-HSA path or trap-handler disabled? then, insert s_endpgm instruction
3595
+ if (ST.getTrapHandlerAbi () != GCNSubtarget::TrapHandlerAbiHsa ||
3596
+ !ST.isTrapHandlerEnabled ()) {
3597
+ B.buildInstr (AMDGPU::S_ENDPGM).addImm (0 );
3598
+ } else {
3599
+ // Pass queue pointer to trap handler as input, and insert trap instruction
3600
+ // Reference: https://llvm.org/docs/AMDGPUUsage.html#trap-handler-abi
3601
+ const ArgDescriptor *Arg =
3602
+ getArgDescriptor (B, AMDGPUFunctionArgInfo::QUEUE_PTR);
3603
+ if (!Arg)
3604
+ return false ;
3605
+ MachineRegisterInfo &MRI = *B.getMRI ();
3606
+ Register SGPR01 (AMDGPU::SGPR0_SGPR1);
3607
+ Register LiveIn = getLiveInRegister (
3608
+ B, MRI, SGPR01, LLT::pointer (AMDGPUAS::CONSTANT_ADDRESS, 64 ),
3609
+ /* InsertLiveInCopy=*/ false );
3610
+ if (!loadInputValue (LiveIn, B, Arg))
3611
+ return false ;
3612
+ B.buildCopy (SGPR01, LiveIn);
3613
+ B.buildInstr (AMDGPU::S_TRAP)
3614
+ .addImm (GCNSubtarget::TrapIDLLVMTrap)
3615
+ .addReg (SGPR01, RegState::Implicit);
3616
+ }
3617
+
3618
+ MI.eraseFromParent ();
3619
+ return true ;
3620
+ }
3621
+
3622
+ bool AMDGPULegalizerInfo::legalizeDebugTrapIntrinsic (
3623
+ MachineInstr &MI, MachineRegisterInfo &MRI, MachineIRBuilder &B) const {
3624
+ B.setInstr (MI);
3625
+
3626
+ // Is non-HSA path or trap-handler disabled? then, report a warning
3627
+ // accordingly
3628
+ if (ST.getTrapHandlerAbi () != GCNSubtarget::TrapHandlerAbiHsa ||
3629
+ !ST.isTrapHandlerEnabled ()) {
3630
+ DiagnosticInfoUnsupported NoTrap (B.getMF ().getFunction (),
3631
+ " debugtrap handler not supported" ,
3632
+ MI.getDebugLoc (), DS_Warning);
3633
+ LLVMContext &Ctx = B.getMF ().getFunction ().getContext ();
3634
+ Ctx.diagnose (NoTrap);
3635
+ } else {
3636
+ // Insert debug-trap instruction
3637
+ B.buildInstr (AMDGPU::S_TRAP).addImm (GCNSubtarget::TrapIDLLVMDebugTrap);
3638
+ }
3639
+
3640
+ MI.eraseFromParent ();
3641
+ return true ;
3642
+ }
3643
+
3561
3644
bool AMDGPULegalizerInfo::legalizeIntrinsic (MachineInstr &MI,
3562
3645
MachineIRBuilder &B,
3563
3646
GISelChangeObserver &Observer) const {
@@ -3732,6 +3815,10 @@ bool AMDGPULegalizerInfo::legalizeIntrinsic(MachineInstr &MI,
3732
3815
return legalizeAtomicIncDec (MI, B, true );
3733
3816
case Intrinsic::amdgcn_atomic_dec:
3734
3817
return legalizeAtomicIncDec (MI, B, false );
3818
+ case Intrinsic::trap:
3819
+ return legalizeTrapIntrinsic (MI, MRI, B);
3820
+ case Intrinsic::debugtrap:
3821
+ return legalizeDebugTrapIntrinsic (MI, MRI, B);
3735
3822
default : {
3736
3823
if (const AMDGPU::ImageDimIntrinsicInfo *ImageDimIntr =
3737
3824
AMDGPU::getImageDimIntrinsicInfo (IntrID))
0 commit comments