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

Friedman, Eli via llvm-dev llvm-dev at lists.llvm.org
Tue Feb 14 10:21:14 PST 2017


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 certainoperations (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 sdivnode. 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 sdivnode is not part of a chain, the EntryTokenis used as 
> the starting point of the chain for the library call. This means that 
> the ordering between the sequence of CopyFromRegnodes and the call 
> sequence can be changed. Specifically, we are seeing the two copies 
> from %reg2and %reg3being 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/20170214/ee997c1f/attachment.html>


More information about the llvm-dev mailing list