[PATCH] Refactor sameNoopInput (determining tail-call legitimacy)

Tim Northover t.p.northover at gmail.com
Mon Jul 29 07:21:56 PDT 2013


Hi Duncan,

Sorry about the delay, I was completely out of contact over the weekend.

On Fri, Jul 26, 2013 at 1:58 PM, Duncan Sands <duncan.sands at gmail.com> wrote:
>> This change came about primarily because of two issues in the existing
>> code. Niether of [the following should be tail calls]:

> why not?

>> define i64 @test1(i64 %val) {
>>    %in = trunc i64 %val to i32
>>    tail call i32 @ret32(i32 returned %in)
>>    ret i64 %val
>> }

In this case, only the low 32-bits of %val are passed to @ret32, but
all 64-bits are required by @test1. There's a good chance these bits
don't exist anywhere any more by the end of @ret32, but they're
certainly not returned by it in an appropriate format for @test1.

For example, on ARM this might compile to:
test1:
    mov r4, r1
    bl ret32
    mov r1, r4
    bx lr

where the two MOV instructions are saving the high bits of %val in a
callee-saved register for later.

>> define i32 @test2() {
>>    tail call i32 @ret32(i32 returned undef)
>>    ret i32 42
>> }

In this case, since @ret32 is given rubbish, it can make no guarantees
about what's actually returned; but @test2 needs to return 42. I
suppose in principle a pass could convert it into:

define i32 @test2() {
  tail call i32 @ret32(i32 returned 42)
  ret i32 42
}

But I think that's probably not the job of SelectionDAGBuilder, which
is where this is happening.

Cheers.

Tim.



More information about the llvm-commits mailing list