Dead Argument Elimination for Recursive Functions With Use in Recursion

Does dead argument elimination work on recursive functions where the value of the recursive call is used to compute the next output?

I’m trying to have LLVM 7 eliminate the return value in the following code snippet, where the return value of rdac (and the add) could be eliminated but is not.

recurret.c
attribute((noinline))
static double rdac(double* x, unsigned n) {
if (n == 1) {
double val = x[0];
x[0] = 0;
return val;
}
return rdac(x, n/2) + rdac(x + n/2, n/2);
}

void dsum(double* x, unsigned n) {
rdac(x, n);
}

recurret.ll:; ModuleID = ‘recurret.c’
source_filename = “recurret.c”
target datalayout = “e-m:e-i64:64-f80:128-n8:16:32:64-S128”
target triple = “x86_64-unknown-linux-gnu”

; Function Attrs: nounwind uwtable
define dso_local void @dsum(double* %x, i32 %n) local_unnamed_addr #0 {
entry:
%call = tail call fast fastcc double @rdac(double* %x, i32 %n)
ret void
}

; Function Attrs: noinline nounwind uwtable
define internal fastcc double @rdac(double* %x, i32 %n) unnamed_addr #1 {
entry:
%cmp = icmp eq i32 %n, 1
br i1 %cmp, label %if.then, label %if.end

if.then: ; preds = %entry
%0 = load double, double* %x, align 8, !tbaa !2
store double 0.000000e+00, double* %x, align 8, !tbaa !2
ret double %0

if.end: ; preds = %entry
%div = lshr i32 %n, 1
%call = tail call fast fastcc double @rdac(double* %x, i32 %div)
%idx.ext = zext i32 %div to i64
%add.ptr = getelementptr inbounds double, double* %x, i64 %idx.ext
%call4 = tail call fast fastcc double @rdac(double* %add.ptr, i32 %div)
}

attributes #0 = { nounwind uwtable “correctly-rounded-divide-sqrt-fp-math”=“false” “disable-tail-calls”=“false” “less-precise-fpmad”=“false” “no-frame-pointer-elim”=“false” “no-infs-fp-math”=“true” “no-jump-tables”=“false” “no-nans-fp-math”=“true” “no-signed-zeros-fp-math”=“true” “no-trapping-math”=“true” “stack-protector-buffer-size”=“8” “target-cpu”=“x86-64” “target-features”=“+fxsr,+mmx,+sse,+sse2,+x87” “unsafe-fp-math”=“true” “use-soft-float”=“false” }
attributes #1 = { noinline nounwind uwtable “correctly-rounded-divide-sqrt-fp-math”=“false” “disable-tail-calls”=“false” “less-precise-fpmad”=“false” “no-frame-pointer-elim”=“false” “no-infs-fp-math”=“true” “no-jump-tables”=“false” “no-nans-fp-math”=“true” “no-signed-zeros-fp-math”=“true” “no-trapping-math”=“true” “stack-protector-buffer-size”=“8” “target-cpu”=“x86-64” “target-features”=“+fxsr,+mmx,+sse,+sse2,+x87” “unsafe-fp-math”=“true” “use-soft-float”=“false” }

!llvm.module.flags = !{!0}
!llvm.ident = !{!1}

!0 = !{i32 1, !“wchar_size”, i32 4}
!1 = !{!"clang version 7.1.0 "}
!2 = !{!3, !3, i64 0}
!3 = !{!“double”, !4, i64 0}
!4 = !{!“omnipotent char”, !5, i64 0}
!5 = !{!“Simple C/C++ TBAA”}