diff options
author | Mike Stump <mrs@apple.com> | 2009-11-05 06:12:26 +0000 |
---|---|---|
committer | Mike Stump <mrs@apple.com> | 2009-11-05 06:12:26 +0000 |
commit | 7c276b84d6881df18c847b036fe3c95d94d9b5b3 (patch) | |
tree | 3287e60b2dc4df7f7156706bd6077682dec15066 /lib/CodeGen/CGCXX.cpp | |
parent | 99faefdac32eda8cf0d6db722588a76caa3add22 (diff) |
Refine covariant return value adjustments for thunks when null
pointers are returned.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@86120 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/CGCXX.cpp')
-rw-r--r-- | lib/CodeGen/CGCXX.cpp | 20 |
1 files changed, 19 insertions, 1 deletions
diff --git a/lib/CodeGen/CGCXX.cpp b/lib/CodeGen/CGCXX.cpp index d4adbad1e4..fd90dc06d5 100644 --- a/lib/CodeGen/CGCXX.cpp +++ b/lib/CodeGen/CGCXX.cpp @@ -811,7 +811,25 @@ llvm::Constant *CodeGenFunction::GenerateCovariantThunk(llvm::Function *Fn, Callee, CallArgs, MD); if (nv_r || v_r) { // Do the return result adjustment. - RV = RValue::get(DynamicTypeAdjust(RV.getScalarVal(), nv_r, v_r)); + llvm::BasicBlock *NonZeroBlock = createBasicBlock(); + llvm::BasicBlock *ZeroBlock = createBasicBlock(); + llvm::BasicBlock *ContBlock = createBasicBlock(); + + const llvm::Type *Ty = RV.getScalarVal()->getType(); + llvm::Value *Zero = llvm::Constant::getNullValue(Ty); + Builder.CreateCondBr(Builder.CreateICmpNE(RV.getScalarVal(), Zero), + NonZeroBlock, ZeroBlock); + EmitBlock(NonZeroBlock); + llvm::Value *NZ = DynamicTypeAdjust(RV.getScalarVal(), nv_r, v_r); + EmitBranch(ContBlock); + EmitBlock(ZeroBlock); + llvm::Value *Z = RV.getScalarVal(); + EmitBlock(ContBlock); + llvm::PHINode *RVOrZero = Builder.CreatePHI(Ty); + RVOrZero->reserveOperandSpace(2); + RVOrZero->addIncoming(NZ, NonZeroBlock); + RVOrZero->addIncoming(Z, ZeroBlock); + RV = RValue::get(RVOrZero); } if (!ResultType->isVoidType()) |