Issue 104770
Summary Unnecessary return statement generated by EmitFunctionEpiloge in musttail cases.
Labels clang, clang:codegen
Assignees kiran-isaac
Reporter kiran-isaac
    When clang::musttail is used, and -O is not set, an extra "function epiloge" return case is generated. This seems to be optimized out at any -O level, and automatially optimized out by the backend. I believe this is the case for all musttail calls, but I have attatched a repro example for conveniance.

Reproduce: 
```cpp
int F1(signed short P0);
int F2(signed short P0) {
  [[clang::musttail]] return F1(2);
}
```
```bash
clang -S -emit-llvm
```
```
define dso_local noundef i32 @_Z2F2s(i16 noundef signext %P0) #0 {
entry:
 %P0.addr = alloca i16, align 2
  store i16 %P0, ptr %P0.addr, align 2
 %call = musttail call noundef i32 @_Z2F1s(i16 noundef signext 2)
  ret i32 %call

0:                                                ; No predecessors!
  ret i32 undef
}
```
The two calls to CreateRet are here:
`CodeGenFunction::EmitCall`
```c++
  // If this is a musttail call, return immediately. We do not branch to the
  // epilogue in this case.
  if (IsMustTail) {
    for (auto it = EHStack.find(CurrentCleanupScopeDepth); it != EHStack.end();
 ++it) {
      EHCleanupScope *Cleanup = dyn_cast<EHCleanupScope>(&*it);
      if (!(Cleanup && Cleanup->getCleanup()->isRedundantBeforeReturn()))
 CGM.ErrorUnsupported(MustTailCall, "tail call skipping over cleanups");
 }
    if (CI->getType()->isVoidTy())
 Builder.CreateRetVoid();
    else
      Builder.CreateRet(CI);
 Builder.ClearInsertionPoint();
    EnsureInsertPoint();
    return GetUndefRValue(RetTy);
  }
```
and here
`CodeGenFunction::EmitFunctionEpilog`
```c++
case ABIArgInfo::IndirectAliased:
    llvm_unreachable("Invalid ABI kind for return argument");
  }

  llvm::Instruction *Ret;
  if (RV) {
    if (CurFuncDecl && CurFuncDecl->hasAttr<CmseNSEntryAttr>()) {
 // For certain return types, clear padding bits, as they may reveal
 // sensitive information.
      // Small struct/union types are passed as integers.
      auto *ITy = dyn_cast<llvm::IntegerType>(RV->getType());
      if (ITy != nullptr && isa<RecordType>(RetTy.getCanonicalType()))
        RV = EmitCMSEClearRecord(RV, ITy, RetTy);
    }
 EmitReturnValueCheck(RV);
    Ret = Builder.CreateRet(RV);
  } else {
    Ret = Builder.CreateRetVoid();
  }
```

I suggest that EmitFunctionEpilog should not be called for a musttail function, as the body definitely already contains a return.
_______________________________________________
llvm-bugs mailing list
llvm-bugs@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs

Reply via email to