[llvm-dev] [SelectionDAG] [TargetOp] How to get sub-half of immediate?

Kevin Choi via llvm-dev llvm-dev at lists.llvm.org
Fri Mar 9 14:13:48 PST 2018


SDNodeXForm worked like a charm.

Thank you very much,

Kevin


On 3/9/2018 4:47 PM, Simon Dardis wrote:
> Hi Kevin,
>
> To get some portion of a constant immediate you can use SDNodeXForms to
> transform constant SDNodes into other values. For a worked example, in the
> MIPS backend we use this for constant synthesis by materializing the value into a
> register:
>
> (From lib/Target/MipsInstrInfo.td):
>   
> // Transformation Function - get the lower 16 bits.
> def LO16 : SDNodeXForm<imm, [{
>    return getImm(N, N->getZExtValue() & 0xFFFF);
> }]>;
>
> The above fragment will take an immediate node and get the lower 16 bits.
>
> // Transformation Function - get the higher 16 bits.
> def HI16 : SDNodeXForm<imm, [{
>    return getImm(N, (N->getZExtValue() >> 16) & 0xFFFF);
> }]>;
>
> Similarly, get the high 16 bits.
>
> def LUiORiPred  : PatLeaf<(imm), [{
>    int64_t SVal = N->getSExtValue();
>    return isInt<32>(SVal) && (SVal & 0xffff);
> }]>;
>
> For completeness sake I've included this, but it's return true there are bits in both
> 16 bit fragments.
>
> Then we use (here VT = i32, ORiOp is our logical or which takes an immediate,
> LUiOp loads the upper bits of a register with an immediate, zeroing the lower 16 bits):
>
> // Arbitrary immediates
> def : MipsPat<(VT LUiORiPred:$imm), (ORiOp (LUiOp (HI16 imm:$imm)), (LO16 imm:$imm))>;
>
> This anonymous pattern matches any sign-extended 32 bit immediate due to
> LUiORiPred, and the expression (HI16 imm:$imm) takes an immediate and
> extracts the upper bits of the immediate into a constant which LUiOp accepts.
> The outer (LO16 imm:$imm) expression gets the lower 16 bits which ORiOp accepts.
>
> As the SDNodeXForm takes arbitrary C++ code, you can go a bit farther with
> transforming values.
>
> Depending on your target, the usage of SDNodeXForm example alone may be
> enough for your needs, otherwise hopefully the synthesize into a register example
> is sufficient.
>
> Thanks,
> Simon
> ________________________________________
> From: llvm-dev [llvm-dev-bounces at lists.llvm.org] on behalf of Kevin Choi via llvm-dev [llvm-dev at lists.llvm.org]
> Sent: Friday, March 9, 2018 8:04 PM
> To: llvm-dev
> Subject: [llvm-dev] [SelectionDAG] [TargetOp] How to get sub-half of immediate?
>
> Hi all,
>
> This seems like a dumb question but while setting up a pattern in TD
> file, I got stuck on trying to get each half of an immediate as the
> half-sized type (ie. i64 imm -> pair of i32 imm's). Is there an existing
> way to do it? I've tried the 'EXTRACT_SUBREG' but that seems to error at
> the end of scheduling. Looking at Target.td, I'm not sure which opcode
> is meant for my need. Copying imm to reg would be another solution but
> I'm also not sure which opcode forces it.
>
> Many Thanks,
>
> Kevin
>
> _______________________________________________
> LLVM Developers mailing list
> llvm-dev at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev



More information about the llvm-dev mailing list