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

Stephen Lin swlin at post.harvard.edu
Tue Jul 30 23:17:34 PDT 2013


>>> 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:
>

You know, I don't disagree that this is the probably the saner and
more developer-friendly call to make, but if you think about it,
generating a tail call is not (as far as I can tell) the incorrect
thing to do here from a C language perspective, because once you pass
an undefined value as a parameter for a call that you're executing
you've entered full-on undefined behavior territory (correct me if I'm
wrong?)

Whether or not this is correct from the LLVM perspective depends on
where the division between "undefined bit pattern" and "undefined
behavior" lies in LLVM IR semantics, and I'm not sure that's
rigorously defined anywhere? Basically, is passing an undefined value
as an argument to a function considered equivalent to passing "an
unspecified bit pattern" or does it trigger "undefined behavior"? For
example, stores to undefined values are defined as undefined behavior,
even in LLVM IR; rather than simply causing the range of possible
effects expressible in LLVM IR; it could be argued that we could
aggressively treat passing an undefined value across an ABI boundary
in the same way.

Anyway, I'm perfectly I'm fine saying that that this is not a case of
"undefined behavior" and merely a case of passing an "undefined bit
pattern" to another function :) I'm just curious if anyone has
rigorously described where the division between "undefined values" and
"undefined behavior" lies in LLVM IR semantics?

Stephen



More information about the llvm-commits mailing list