[PATCH] Fix detection of devirtualized calls that have no users

Rafael Espíndola rafael.espindola at gmail.com
Thu Feb 20 15:05:36 PST 2014


LGTM with a comment explaining why we are calling ValueHandleBase::ValueIsRAUWd.

On 10 February 2014 14:08, Björn Steinbrink <bsteinbr at gmail.com> wrote:
> In transformConstExprCastCall, if the replaced call has no users, we
> currently don't call ReplaceInstUsesWith, which means that ValueHandlers
> aren't notified about the replacement, but only about the removal of the
> old call.
>
> This means that we can't immediately detect the devirtualization of such
> calls when updating the call graph in the CGSCC pass, because the old
> CallSite got invalidated. If some other change then fools the simple
> counting logic, we fail to re-run the pass on the current function,
> missing further optimization possibilities opened up by the
> devirtualized call.
>
> As a fix, we should manually perform the notifications if there are
> ValueHandlers present.
> ---
>  lib/Transforms/InstCombine/InstCombineCalls.cpp  |  2 ++
>  test/Transforms/InstCombine/cast-call-combine.ll | 22 ++++++++++++++++++++++
>  2 files changed, 24 insertions(+)
>  create mode 100644 test/Transforms/InstCombine/cast-call-combine.ll
>
> diff --git a/lib/Transforms/InstCombine/InstCombineCalls.cpp b/lib/Transforms/InstCombine/InstCombineCalls.cpp
> index 8e308ec..cba88ff 100644
> --- a/lib/Transforms/InstCombine/InstCombineCalls.cpp
> +++ b/lib/Transforms/InstCombine/InstCombineCalls.cpp
> @@ -1227,6 +1227,8 @@ bool InstCombiner::transformConstExprCastCall(CallSite CS) {
>
>    if (!Caller->use_empty())
>      ReplaceInstUsesWith(*Caller, NV);
> +  else if (Caller->hasValueHandle())
> +    ValueHandleBase::ValueIsRAUWd(Caller, NV);
>
>    EraseInstFromFunction(*Caller);
>    return true;
> diff --git a/test/Transforms/InstCombine/cast-call-combine.ll b/test/Transforms/InstCombine/cast-call-combine.ll
> new file mode 100644
> index 0000000..4eb2478
> --- /dev/null
> +++ b/test/Transforms/InstCombine/cast-call-combine.ll
> @@ -0,0 +1,22 @@
> +; RUN: opt < %s -always-inline -instcombine -S | FileCheck %s
> +
> +define internal void @foo(i16*) alwaysinline {
> +  ret void
> +}
> +
> +define void @bar() noinline noreturn {
> +  unreachable
> +}
> +
> +define void @test() {
> +  br i1 false, label %then, label %else
> +
> +then:
> +  call void @bar()
> +  unreachable
> +
> +else:
> +  ; CHECK-NOT: call
> +  call void bitcast (void (i16*)* @foo to void (i8*)*) (i8* null)
> +  ret void
> +}
> --
> 1.9.0.rc3
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits




More information about the llvm-commits mailing list