[llvm-dev] Ensuring chain dependencies with expansion to libcalls

Stephen Rogers via llvm-dev llvm-dev at lists.llvm.org
Wed Feb 15 03:46:08 PST 2017


Thanks Eli,

This was exactly the problem. Using virtual registers for our function
arguments has fixed it.

All the best,
Stephen

On 14 February 2017 at 18:21, Friedman, Eli <efriedma at codeaurora.org> wrote:

> On 2/14/2017 3:27 AM, Stephen Rogers via llvm-dev wrote:
>
> Hi all,
>
> Our target does not have native support for 64-bit integers, so we rely on
> library calls for certain operations (like sdiv). We recently ran into a
> problem where these operations that are expanded to library calls aren't
> maintaining the proper ordering in relation to other chains in the DAG.
>
> The following snippet of a DAG demonstrates the problem.
>
>   t0: ch = EntryToken
>   t2: i64,ch,glue = CopyFromReg t0, Register:i64 %reg0
>   t4: i64,ch,glue = CopyFromReg t2:1, Register:i64 %reg1, t2:1
>   t6: i64,ch,glue = CopyFromReg t4:1, Register:i64 %reg2, t4:1
>   t8: i64,ch,glue = CopyFromReg t6:1, Register:i64 %reg3, t6:1
>         t11: ch = CopyToReg t0, Register:i64 %vreg0, t2
>         t13: ch = CopyToReg t0, Register:i64 %vreg1, t4
>         t15: ch = CopyToReg t0, Register:i64 %vreg2, t8
>       t26: ch = TokenFactor t11, t13, t15, t2:1, t4:1, t6:1, t8:1
>       t16: i64 = sdiv t2, t4
>
> Before legalization, there is a single sdiv node. After legalization,
> this has been expanded to a call sequence:
>
>   t0: ch = EntryToken
>   t2: i64,ch,glue = CopyFromReg t0, Register:i64 %reg0
>   t4: i64,ch,glue = CopyFromReg t2:1, Register:i64 %reg1, t2:1
>   t6: i64,ch,glue = CopyFromReg t4:1, Register:i64 %reg2, t4:1
>   t8: i64,ch,glue = CopyFromReg t6:1, Register:i64 %reg3, t6:1
>     t46: ch,glue = callseq_start t0, TargetConstant:i32<0>
>   t47: ch,glue = CopyToReg t46, Register:i64 %reg0, t2
>   t48: ch,glue = CopyToReg t47, Register:i64 %reg1, t4, t47:1
>   t50: ch,glue = SHAVEISD::CALL t48, TargetExternalSymbol:i32'__divdi3',
> Register:i64 %reg0, Register:i64 %reg1, RegisterMask:Untyped, t48:1
>   t51: ch,glue = callseq_end t50, TargetConstant:i32<0>,
> TargetExternalSymbol:i32'__divdi3', t50:1
>   t52: i64,ch,glue = CopyFromReg t51, Register:i64 %reg0, t51:1
>         t11: ch = CopyToReg t0, Register:i64 %vreg0, t2
>         t13: ch = CopyToReg t0, Register:i64 %vreg1, t4
>         t15: ch = CopyToReg t0, Register:i64 %vreg2, t8
>       t26: ch = TokenFactor t11, t13, t15, t2:1, t4:1, t6:1, t8:1
>
> Since the sdiv node is not part of a chain, the EntryToken is used as the
> starting point of the chain for the library call. This means that the
> ordering between the sequence of CopyFromReg nodes and the call sequence
> can be changed. Specifically, we are seeing the two copies from %reg2 and
> %reg3 being moved to after the call sequence. This is a problem since the
> library call clobbers both of these registers (since they are caller-saved
> registers).
>
>
> "CopyFromReg t0, Register:i64 %reg0" is your problem: as you've
> discovered, you can't model function arguments like this.  If you look at
> the debug output for an in-tree target (e.g. 32-bit ARM), you'll find that
> the CopyFromReg nodes for register arguments are copies from virtual
> registers.  See MachineFunction::addLiveIn.
>
> -Eli
>
> --
> Employee of Qualcomm Innovation Center, Inc.
> Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, a Linux Foundation Collaborative Project
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20170215/ef0ae092/attachment-0001.html>


More information about the llvm-dev mailing list