From: Reed Kotler Date: Wed, 18 Dec 2013 23:57:48 +0000 (+0000) Subject: Fix a problem with mips16 stubs when calls are transformed during X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=deb8e33163b237cecb58eacb90168155eee0573f;p=oota-llvm.git Fix a problem with mips16 stubs when calls are transformed during tail call optimization. Some more work may be needed for indirect calls but this patch fixes the current regression in Prolangc++/trees. S2 optimization as part of the general cleanup and optimization of prolog and epilog was not saving S2 in this case and needed to. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@197630 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Target/Mips/Mips16HardFloat.cpp b/lib/Target/Mips/Mips16HardFloat.cpp index 65dbd74a1c8..cb0ea869887 100644 --- a/lib/Target/Mips/Mips16HardFloat.cpp +++ b/lib/Target/Mips/Mips16HardFloat.cpp @@ -13,6 +13,7 @@ #define DEBUG_TYPE "mips16-hard-float" #include "Mips16HardFloat.h" +#include "llvm/IR/Value.h" #include "llvm/IR/Module.h" #include "llvm/Support/Debug.h" #include "llvm/Support/raw_ostream.h" @@ -167,6 +168,11 @@ static bool needsFPReturnHelper(Function &F) { return whichFPReturnVariant(RetType) != NoFPRet; } +static bool needsFPReturnHelper(const FunctionType &FT) { + Type* RetType = FT.getReturnType(); + return whichFPReturnVariant(RetType) != NoFPRet; +} + static bool needsFPHelperFromSig(Function &F) { return needsFPStubFromParams(F) || needsFPReturnHelper(F); } @@ -400,7 +406,19 @@ static bool fixupFPReturnAndCall Value *F = (M->getOrInsertFunction(Name, A, MyVoid, T, NULL)); CallInst::Create(F, Params, "", &Inst ); } else if (const CallInst *CI = dyn_cast(I)) { + const Value* V = CI->getCalledValue(); + const Type* T = 0; + if (V) T = V->getType(); + const PointerType *PFT=0; + if (T) PFT = dyn_cast(T); + const FunctionType *FT=0; + if (PFT) FT = dyn_cast(PFT->getElementType()); Function *F_ = CI->getCalledFunction(); + if (FT && needsFPReturnHelper(*FT) && + !(F_ && isIntrinsicInline(F_))) { + Modified=true; + F.addFnAttr("saveS2"); + } if (F_ && !isIntrinsicInline(F_)) { // pic mode calls are handled by already defined // helper functions diff --git a/test/CodeGen/Mips/tail16.ll b/test/CodeGen/Mips/tail16.ll new file mode 100644 index 00000000000..4e62e557478 --- /dev/null +++ b/test/CodeGen/Mips/tail16.ll @@ -0,0 +1,20 @@ +; RUN: llc -mtriple=mipsel-linux-gnu -march=mipsel -mcpu=mips16 -soft-float -mips16-hard-float -relocation-model=pic < %s | FileCheck %s + +; Function Attrs: nounwind optsize +define float @h() { +entry: + %call = tail call float bitcast (float (...)* @g to float ()*)() + ret float %call +; CHECK: .ent h +; CHECK: save $16, $ra, $18, 32 +; CHECK: lw ${{[0-9]+}}, %got(__mips16_call_stub_sf_0)(${{[0-9]+}}) +; CHECK: restore $16, $ra, $18, 32 +; CHECK: .end h +} + +; Function Attrs: optsize +declare float @g(...) + + + +