This is an archive of the discontinued LLVM Phabricator instance.

[CodeGen] Enable tail call position check for speculatable functions
ClosedPublic

Authored by NeHuang on May 27 2020, 1:53 PM.

Details

Summary

In the function "Analysis.cpp:isInTailCallPosition", it only checks whether a call is in a tail call position if the call has side effects, access memory or it is not safe to speculative execute. Therefore, a speculatable function will not go through tail call position check and improperly tail called when it is not in a tail-call position. An example as below:

IR reproducer

define dso_local void @caller(double* nocapture %res, double %a) local_unnamed_addr #0 {
entry:
  %call = tail call double @callee(double %a) #2
  store double %call, double* %res, align 8
  ret void
}
define double @callee(double) local_unnamed_addr #1 {
  ret double 4.5
}
attributes #0 = { nounwind }
attributes #1 = { readnone speculatable }
attributes #2 = { nounwind noinline }

produces a tail call in the caller without storing the result, which can be seen in the initial SDAG below

llc < reproducer.ll -debug-only=isel -mtriple=x86_64
=== caller
Initial selection DAG: %bb.0 'caller:entry'
SelectionDAG has 12 nodes:
  t0: ch = EntryToken
  t2: i64,ch = CopyFromReg t0, Register:i64 %0
  t5: i64 = GlobalAddress<double (double)* @callee> 0
    t4: f64,ch = CopyFromReg t0, Register:f64 %1
  t7: ch,glue = CopyToReg t0, Register:f64 $xmm0, t4
  t11: ch,glue = X86ISD::TC_RETURN t7, TargetGlobalAddress:i64<double (double)* @callee> 0, Constant:i32<0>, Register:f64 $xmm0, RegisterMask:Untyped, t7:1

This patch enables tail call position check for speculatable functions.

Diff Detail

Event Timeline

NeHuang created this revision.May 27 2020, 1:53 PM

Test for speculatable with a single return use but intermediate instructions missing.

Test for speculatable with a single return use but intermediate instructions missing.

Thanks for your input. "@speculatable_callee_return_use_only" was created for single return use case in "tailcall-speculatable-callee.ll".

Test for speculatable with a single return use but intermediate instructions missing.

Sorry, I misunderstood your point in previous comment. I am adding and verifying a case where intermediate instructions (not use the result of callee) added between the speculatable callee and the return instruction.

Test for speculatable with a single return use but intermediate instructions missing.

Sorry, I misunderstood your point in previous comment. I am adding and verifying a case where intermediate instructions (not use the result of callee) added between the speculatable callee and the return instruction.

That's what I meant, thx :)

NeHuang updated this revision to Diff 267936.Jun 2 2020, 12:20 PM
NeHuang edited the summary of this revision. (Show Details)

Previously we have an assumption that speculatable callee will be moved down if there are intermediate instructions (not using the result of callee) between it and the return instruction. However, the assumption does not hold in our experiment that no passes in opt or llc will move the speculatable callee down. Therefore we need to handle speculatable calls same as the other calls in bool llvm::isInTailCallPosition that checking if it is in a tail call position.

Added a new test case that intermediate instructions (not use result of callee) between speculatable callee and the return instruction.

jdoerfert accepted this revision.Jun 2 2020, 1:12 PM

LGTM, one nit below.

llvm/test/CodeGen/PowerPC/tailcall-speculatable-callee.ll
61

Please add a FIXME explaining this call could be moved to make it a tail call.

This revision is now accepted and ready to land.Jun 2 2020, 1:12 PM
This revision was automatically updated to reflect the committed changes.