<div dir="ltr"><div style>Hi all,</div><div><br></div>I'm trying to start using the LiveOuts-exporting feature of the new stackmap/patchpoint intrinsics, and I'm running into some issues where I seem to be getting the wrong set of registers.  This is my first foray into CodeGen, so my understanding of everything I'm about to say is pretty hazy, but I believe that the stackmap/patchpoint functionality simply tacks on the existing LiveOuts that are already being calculated, which makes me think the issues I'm about to describe are about the LiveOuts calculation rather than being stackmap/patchpoint-specific.<div>

<br></div><div style>I'm running into an issue where I get some registers in the LiveOuts set that are clearly not live after the call; specifically, I'm sometimes get that %rdi or %rsi are live after a function call which uses a normal C-calling convention.  Or maybe I'm misunderstanding the meaning of LiveOuts; I'm assuming that they refer to registers that contain values that will be used later.</div>

<div style><br></div><div style>Here's a boiled-down version of the IR:</div><div style><div><font face="courier new, monospace">define void @f(i64) {</font></div><div><font face="courier new, monospace">  %2 = load %0** @n, align 8</font></div>

<div><font face="courier new, monospace">  %3 = getelementptr inbounds %0* %2, i64 0, i32 0</font></div><div><font face="courier new, monospace">  %4 = call i1 @foo()</font></div><div><font face="courier new, monospace">  br i1 %4, label %9, label %5</font></div>

<div><font face="courier new, monospace"><br></font></div><div><font face="courier new, monospace">; <label>:5                                       ; preds = %5, %1</font></div><div><font face="courier new, monospace">  %6 = phi i64* [ %3, %5 ], [ %3, %1 ]</font></div>

<div><font face="courier new, monospace">  %7 = tail call i64 (i64, i32, i8*, i32, ...)* @llvm.experimental.patchpoint.i64(i64 116, i32 13, i8* inttoptr (i64 12346 to i8*), i32 3, i64 %0, i64 1, i64* %6)</font></div><div>

<font face="courier new, monospace">  %8 = call i1 @foo()</font></div><div><font face="courier new, monospace">  br i1 %8, label %9, label %5</font></div><div><font face="courier new, monospace"><br></font></div><div><font face="courier new, monospace">; <label>:9                                       ; preds = %5, %1</font></div>

<div><font face="courier new, monospace">  ret void</font></div><div><font face="courier new, monospace">}</font></div><div><br></div><div style>And here's the generated assembly listing:</div><div style><div><font face="courier new, monospace">f:</font></div>

<div><font face="courier new, monospace">        pushq   %r14</font></div><div><span style="font-family:'courier new',monospace">        pushq   %rbx</span><br></div><div><span style="font-family:'courier new',monospace">        pushq   %rax</span><br>

</div><div><span style="font-family:'courier new',monospace">        movq    %rdi, %r14</span><br></div><div><font face="courier new, monospace">        movq    n(%rip), %rbx</font></div><div><font face="courier new, monospace">        jmp     .LBB0_2</font></div>

<div><font face="courier new, monospace">        .align  16, 0x90</font></div><div><font face="courier new, monospace">.LBB0_1:</font></div><div><font face="courier new, monospace">        movl    $1, %esi</font></div><div>

<font face="courier new, monospace">        movq    %r14, %rdi</font></div><div><font face="courier new, monospace">        movq    %rbx, %rdx</font></div><div><span style="font-family:'courier new',monospace">        movabsq $12346, %r11</span><br>

</div><div><font face="courier new, monospace">        callq   *%r11</font></div><div><font face="courier new, monospace">.LBB0_2:</font></div><div><font face="courier new, monospace">        callq   foo</font></div><div>

<font face="courier new, monospace">        testb   $1, %al</font></div><div><font face="courier new, monospace">        je      .LBB0_1</font></div><div style><font face="courier new, monospace">.LBB0_3:</font></div><div>

<font face="courier new, monospace">        addq    $8, %rsp</font></div><div><font face="courier new, monospace">        popq    %rbx</font></div><div><font face="courier new, monospace">        popq    %r14</font></div>

<div><font face="courier new, monospace">        retq</font></div><div><br></div><div style>It's claiming that %rdi is live after the "callq %r11" at the end of LBB0_1, which based on my understanding of what the live outs are supposed to represent shouldn't be true.  Looking into it, it seems to be because it considers the live outs of LBB0_1 to include RDI; it seems to determine that because RDI is included in the live-ins of LBB0_2.  Again, assuming my understanding of what live-ins are supposed to be is correct, that seems wrong.</div>

<div style><br></div><div style>Tracing through when RDI gets added to that set, it's during block tail-merging.  Specifically, it's in the BranchFolder::MaintainLiveIns(), which does a forward propagation of the BB that I haven't completely dug into; it's working on this basic block:</div>

<div style><div><font face="courier new, monospace">BB#0: derived from LLVM BB %1</font></div><div><font face="courier new, monospace">    Live Ins: %RDI %R14 %RBX</font></div><div><font face="courier new, monospace">        PUSH64r %R14<kill>, %RSP<imp-def>, %RSP<imp-use>; flags: FrameSetup</font></div>

<div><font face="courier new, monospace">        PROLOG_LABEL <MCSym=.Ltmp0></font></div><div><font face="courier new, monospace">        PUSH64r %RBX<kill>, %RSP<imp-def>, %RSP<imp-use>; flags: FrameSetup</font></div>

<div><font face="courier new, monospace">        PROLOG_LABEL <MCSym=.Ltmp1></font></div><div><font face="courier new, monospace">        PUSH64r %RAX<undef>, %RSP<imp-def>, %RSP<imp-use>; flags: FrameSetup</font></div>

<div><font face="courier new, monospace">        PROLOG_LABEL <MCSym=.Ltmp2></font></div><div><font face="courier new, monospace">        %R14<def> = COPY %RDI</font></div><div><font face="courier new, monospace">        %RBX<def> = MOV64rm %RIP, 1, %noreg, <ga:@n>, %noreg; mem:LD8[@n]</font></div>

<div><font face="courier new, monospace">        CALL64pcrel32 <ga:@foo>, <regmask>, %RSP<imp-use>, %RSP<imp-def>, %AL<imp-def></font></div><div><font face="courier new, monospace">        TEST8ri %AL<kill>, 1, %EFLAGS<imp-def></font></div>

<div><font face="courier new, monospace">        JE_4 <BB#2>, %EFLAGS<imp-use></font></div><div><font face="courier new, monospace">    Successors according to CFG: BB#3(16) BB#2(16)</font></div><div><br></div>

<div style>The register scavanger determines that rdi is a live out of this block [that doesn't seem to be the case?] so the tail-merger adds it as a live-in of what will become LBB0_2 (seems weird as well, since they're at exit of BB#0 doesn't correspond to the entry of LBB0_2).  At this point I'm pretty confused -- am I misunderstanding what LiveOuts are supposed to be?  Or does BranchFolder::MaintainLiveIns do the wrong thing?  Or is the register scavanger calculating the liveness differently?  I'm not that clear on how the liveness information is used at different points in the pipeline, and clearly something isn't adding up for me, so if anyway could shed some light on this I'd much appreciate it...</div>

<div style><br></div><div style><br></div><div style>Kevin</div></div></div></div></div>