Mikael Holmén via llvm-dev
2016-Mar-30 09:58 UTC
[llvm-dev] Instruction selection pattern for intrinsic returning llvm_any_ty
On 03/30/2016 11:51 AM, Matt Arsenault wrote:> >> On Mar 30, 2016, at 11:43, Mikael Holmén <mikael.holmen at ericsson.com> wrote: >> >> Hi, >> >> On 03/30/2016 11:38 AM, Matt Arsenault wrote: >>> >>>> On Mar 30, 2016, at 11:35, Mikael Holmén <mikael.holmen at ericsson.com >>>> <mailto:mikael.holmen at ericsson.com>> wrote: >>>> >>>> i16 (divm16_pseudo …) >>>> >>>> stuff? >>>> >>>> I've tried >>>> (i16, i16 (divm16_pseudo i16:$src1, i16:$src2) >>>> and >>>> ((i16, i16) (divm16_pseudo i16:$src1, i16:$src2) >>>> and a few other variants without managing to get it through. >>>> >>>> Thanks again, >>>> Mikael >>> >>> Are you trying to return multiple values? >> >> Yes, the intrisic returns a record >> >> %rec6 = type { i16, i16 } >> >> so at instructions selection the original call >> >> %_tmp3 = call %rec6 @llvm.phx.divm.u16.rec6(i16 %_tmp1, i16 %_tmp2) >> >> has been lowered to >> >> t6: i16,i16 = llvm.phx.divm.u16 TargetConstant:i16<3778>, t2, t4 >> >> and the instruction I want to select also returns two values >> >> def divm16_pseudo : MyPseudoInst< >> (outs aNh_0_7:$dst, aNh_0_7:$dst2), >> (ins aNh_0_7:$src1, aNh_0_7:$src2)>; >> >> Both outs are i16. >> >> /Mikael >> > > The intrinsic itself should define multiple IR outputs rather than using any ty.But the intrinsic returns a record so in the input ll-file it is one result %_tmp3 = call %rec6 @llvm.phx.divm.u16.rec6(i16 %_tmp1, i16 %_tmp2) and then the return value struct is lowered to two i16:s by SelectionDAGISel::SelectBasicBlock: // Lower the instructions. If a call is emitted as a tail call, cease emitting // nodes for this block. for (BasicBlock::const_iterator I = Begin; I != End && !SDB->HasTailCall; ++I) SDB->visit(*I); just prior to the selection.> I’m also not sure if tablegen currently supports patterns with multiple resultsYes, me neither... /Mikael> > -Matt >
Matt Arsenault via llvm-dev
2016-Mar-30 10:01 UTC
[llvm-dev] Instruction selection pattern for intrinsic returning llvm_any_ty
> On Mar 30, 2016, at 11:58, Mikael Holmén <mikael.holmen at ericsson.com> wrote: > > > > On 03/30/2016 11:51 AM, Matt Arsenault wrote: >> >>> On Mar 30, 2016, at 11:43, Mikael Holmén <mikael.holmen at ericsson.com> wrote: >>> >>> Hi, >>> >>> On 03/30/2016 11:38 AM, Matt Arsenault wrote: >>>> >>>>> On Mar 30, 2016, at 11:35, Mikael Holmén <mikael.holmen at ericsson.com >>>>> <mailto:mikael.holmen at ericsson.com>> wrote: >>>>> >>>>> i16 (divm16_pseudo …) >>>>> >>>>> stuff? >>>>> >>>>> I've tried >>>>> (i16, i16 (divm16_pseudo i16:$src1, i16:$src2) >>>>> and >>>>> ((i16, i16) (divm16_pseudo i16:$src1, i16:$src2) >>>>> and a few other variants without managing to get it through. >>>>> >>>>> Thanks again, >>>>> Mikael >>>> >>>> Are you trying to return multiple values? >>> >>> Yes, the intrisic returns a record >>> >>> %rec6 = type { i16, i16 } >>> >>> so at instructions selection the original call >>> >>> %_tmp3 = call %rec6 @llvm.phx.divm.u16.rec6(i16 %_tmp1, i16 %_tmp2) >>> >>> has been lowered to >>> >>> t6: i16,i16 = llvm.phx.divm.u16 TargetConstant:i16<3778>, t2, t4 >>> >>> and the instruction I want to select also returns two values >>> >>> def divm16_pseudo : MyPseudoInst< >>> (outs aNh_0_7:$dst, aNh_0_7:$dst2), >>> (ins aNh_0_7:$src1, aNh_0_7:$src2)>; >>> >>> Both outs are i16. >>> >>> /Mikael >>> >> >> The intrinsic itself should define multiple IR outputs rather than using any ty. > > But the intrinsic returns a record so in the input ll-file it is one result > > %_tmp3 = call %rec6 @llvm.phx.divm.u16.rec6(i16 %_tmp1, i16 %_tmp2) > > and then the return value struct is lowered to two i16:s byThis seems like a strange way to do it. Do you need it to be an arbitrary struct type for some reason? Having multiple result types that expand into a struct would be more normal> > SelectionDAGISel::SelectBasicBlock: > > // Lower the instructions. If a call is emitted as a tail call, cease emitting > // nodes for this block. > for (BasicBlock::const_iterator I = Begin; I != End && !SDB->HasTailCall; ++I) > SDB->visit(*I); > > just prior to the selection. > >> I’m also not sure if tablegen currently supports patterns with multiple results > > Yes, me neither... > > /Mikael > >> >> -Matt-------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20160330/b10adafe/attachment.html>
Mikael Holmén via llvm-dev
2016-Mar-30 11:13 UTC
[llvm-dev] Instruction selection pattern for intrinsic returning llvm_any_ty
Hi,>>> The intrinsic itself should define multiple IR outputs rather than >>> using any ty. >> >> But the intrinsic returns a record so in the input ll-file it is one >> result >> >> %_tmp3 = call %rec6 @llvm.phx.divm.u16.rec6(i16 %_tmp1, i16 %_tmp2) >> >> and then the return value struct is lowered to two i16:s by > > This seems like a strange way to do it. Do you need it to be an > arbitrary struct type for some reason?Not really. At the C level we have typedef struct { __u16_t quotient; __u16_t remainder; } __divm16_t; __divm16_t __divm_u16(__u16_t, __u16_t); and our frontend translates calls to this function to calls to our intrisic %_tmp3 = call %rec6 @llvm.phx.divm.u16.rec6(i16 %_tmp1, i16 %_tmp2) and then we translate it tou our hardware instruction divm (which produces two i16 values). We could probably change our frontend so the intrinsic produces two values rather than the struct, but if tablegen will not accept a pattern with multiple results (which I've no idea if it does or not, but at least I don't know what the syntax would be for it) we won't gain anything from this anyway. The code we have works, only that we need to handle all instrisics like this "manually" in ISelDAGToDAG and I would prefer to write patterns for the selection instead, but it seems it's not very straight forward, if even possible. Thanks for your help, Mikael> Having multiple result types that > expand into a struct would be more normal > > >> >> SelectionDAGISel::SelectBasicBlock: >> >> // Lower the instructions. If a call is emitted as a tail call, cease >> emitting >> // nodes for this block. >> for (BasicBlock::const_iterator I = Begin; I != End && >> !SDB->HasTailCall; ++I) >> SDB->visit(*I); >> >> just prior to the selection. >> >>> I’m also not sure if tablegen currently supports patterns with >>> multiple results >> >> Yes, me neither... >> >> /Mikael >> >>> >>> -Matt >
Apparently Analagous Threads
- Instruction selection pattern for intrinsic returning llvm_any_ty
- Instruction selection pattern for intrinsic returning llvm_any_ty
- Instruction selection pattern for intrinsic returning llvm_any_ty
- Instruction selection pattern for intrinsic returning llvm_any_ty
- Instruction selection pattern for intrinsic returning llvm_any_ty