-
Notifications
You must be signed in to change notification settings - Fork 15.1k
[SPIRV] Implement translation for llvm.modf.* intrinsics #147556
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 7 commits
5bfcf33
7d87ed3
e07f915
cdc2571
4a17c21
e803ef6
4f91ce4
435d636
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -296,6 +296,8 @@ class SPIRVInstructionSelector : public InstructionSelector { | |||||
| bool selectImageWriteIntrinsic(MachineInstr &I) const; | ||||||
| bool selectResourceGetPointer(Register &ResVReg, const SPIRVType *ResType, | ||||||
| MachineInstr &I) const; | ||||||
| bool selectModf(Register ResVReg, const SPIRVType *ResType, | ||||||
| MachineInstr &I) const; | ||||||
|
|
||||||
| // Utilities | ||||||
| std::pair<Register, bool> | ||||||
|
|
@@ -3207,6 +3209,9 @@ bool SPIRVInstructionSelector::selectIntrinsic(Register ResVReg, | |||||
| case Intrinsic::spv_discard: { | ||||||
| return selectDiscard(ResVReg, ResType, I); | ||||||
| } | ||||||
| case Intrinsic::modf: { | ||||||
| return selectModf(ResVReg, ResType, I); | ||||||
| } | ||||||
| default: { | ||||||
| std::string DiagMsg; | ||||||
| raw_string_ostream OS(DiagMsg); | ||||||
|
|
@@ -3990,6 +3995,83 @@ bool SPIRVInstructionSelector::selectLog10(Register ResVReg, | |||||
| .constrainAllUses(TII, TRI, RBI); | ||||||
| } | ||||||
|
|
||||||
| bool SPIRVInstructionSelector::selectModf(Register ResVReg, | ||||||
| const SPIRVType *ResType, | ||||||
| MachineInstr &I) const { | ||||||
| // llvm.modf has a single arg --the number to be decomposed-- and returns a | ||||||
| // struct { restype, restype }, while OpenCLLIB::modf has two args --the | ||||||
| // number to be decomposed and a pointer--, returns the fractional part and | ||||||
| // the integral part is stored in the pointer argument. Therefore, we can't | ||||||
| // use directly the OpenCLLIB::modf intrinsic. However, we can do some | ||||||
| // scaffolding to make it work. The idea is to create an alloca instruction | ||||||
| // to get a ptr, pass this ptr to OpenCL::modf, and then load the value | ||||||
| // from this ptr to place it in the struct. llvm.modf returns the fractional | ||||||
| // part as the first element of the result, and the integral part as the | ||||||
| // second element of the result. | ||||||
|
|
||||||
| // At this point, the return type is not a struct anymore, but rather two | ||||||
| // independent elements of SPIRVResType. We can get each independent element | ||||||
| // from I.getDefs() or I.getOperands(). | ||||||
| if (STI.canUseExtInstSet(SPIRV::InstructionSet::OpenCL_std)) { | ||||||
| MachineIRBuilder MIRBuilder(I); | ||||||
| // Get pointer type for alloca variable. | ||||||
| const SPIRVType *PtrType = GR.getOrCreateSPIRVPointerType( | ||||||
| ResType, MIRBuilder, SPIRV::StorageClass::Function); | ||||||
| // Create new register for the pointer type of alloca variable. | ||||||
| Register PtrTyReg = | ||||||
| MIRBuilder.getMRI()->createVirtualRegister(&SPIRV::iIDRegClass); | ||||||
| MIRBuilder.getMRI()->setType( | ||||||
| PtrTyReg, | ||||||
| LLT::pointer(storageClassToAddressSpace(SPIRV::StorageClass::Function), | ||||||
| GR.getPointerSize())); | ||||||
| // Assign SPIR-V type of the pointer type of the alloca variable to the | ||||||
| // new register. | ||||||
| GR.assignSPIRVTypeToVReg(PtrType, PtrTyReg, MIRBuilder.getMF()); | ||||||
| MachineBasicBlock &EntryBB = I.getMF()->front(); | ||||||
| MachineBasicBlock::iterator VarPos = | ||||||
| getPosForOpVariableWithinBlock(EntryBB); | ||||||
|
||||||
| getPosForOpVariableWithinBlock(EntryBB); | |
| getFirstValidInstructionInsertPoint(EntryBB); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done in 435d636
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -995,4 +995,26 @@ unsigned getArrayComponentCount(const MachineRegisterInfo *MRI, | |||||
| return foldImm(ResType->getOperand(2), MRI); | ||||||
| } | ||||||
|
|
||||||
| MachineBasicBlock::iterator | ||||||
| getPosForOpVariableWithinBlock(MachineBasicBlock &BB) { | ||||||
|
||||||
| getPosForOpVariableWithinBlock(MachineBasicBlock &BB) { | |
| getFirstValidInstructionInsertPoint(MachineBasicBlock &BB) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done in 435d636
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| return VarPos; | |
| return VarPos != BB.end() && VarPos->getOpcode() == SPIRV::OpLabel ? ++VarPos : VarPos; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done in 435d636, but it should never happen, OpLabel is generated later.
Uh oh!
There was an error while loading. Please reload this page.