Handle merging of nativeint and unmanaged pointers as PHI operand types.

We hit these cases in IL stubs in Roslyn bring-up.
This commit is contained in:
Eugene Rozenfeld 2015-04-20 16:02:39 -07:00
Родитель 2ad3639ae1
Коммит 4f6c955d5e
2 изменённых файлов: 24 добавлений и 2 удалений

Просмотреть файл

@ -1142,6 +1142,12 @@ private:
bool isManagedPointerType(llvm::Type *Type);
bool isManagedAggregateType(llvm::Type *Type);
/// \brief Check whether Type is an unmanaged pointer type.
///
/// \param Type Type to check.
/// \returns true iff \p Type is an unmanaged pointer type.
bool isUnmanagedPointerType(llvm::Type *Type);
llvm::StoreInst *makeStore(llvm::Value *ValueToStore, llvm::Value *Address,
bool IsVolatile, bool AddressMayBeNull = true);
llvm::StoreInst *makeStoreNonNull(llvm::Value *ValueToStore,

Просмотреть файл

@ -1855,6 +1855,10 @@ bool GenIR::isManagedType(Type *Type) {
return isManagedPointerType(Type) || isManagedAggregateType(Type);
}
bool GenIR::isUnmanagedPointerType(llvm::Type *Type) {
return Type->isPointerTy() && !isManagedPointerType(Type);
}
#pragma endregion
#pragma region FLOW GRAPH
@ -5645,8 +5649,14 @@ Value *GenIR::ChangePHIOperandType(Value *Operand, BasicBlock *OperandBlock,
Type *NewTy) {
LLVMBuilder->SetInsertPoint(OperandBlock->getTerminator());
if (NewTy->isIntegerTy()) {
bool IsSigned = true;
return LLVMBuilder->CreateIntCast(Operand, NewTy, IsSigned);
Type *OperandTy = Operand->getType();
if (OperandTy->isIntegerTy()) {
bool IsSigned = true;
return LLVMBuilder->CreateIntCast(Operand, NewTy, IsSigned);
} else {
assert(isUnmanagedPointerType(OperandTy));
return LLVMBuilder->CreatePtrToInt(Operand, NewTy);
}
} else if (NewTy->isFloatingPointTy()) {
return LLVMBuilder->CreateFPCast(Operand, NewTy);
} else {
@ -5677,6 +5687,12 @@ Type *GenIR::getStackMergeType(Type *Ty1, Type *Ty2) {
return DoubleTy;
}
// If we have unmanaged pointer and nativeint the result is nativeint.
if ((isUnmanagedPointerType(Ty1) && (Ty2 == NativeIntTy)) ||
(isUnmanagedPointerType(Ty2) && (Ty1 == NativeIntTy))) {
return NativeIntTy;
}
// If we have GC pointers, the result is the closest common supertype.
PointerType *PointerTy1 = dyn_cast<PointerType>(Ty1);
PointerType *PointerTy2 = dyn_cast<PointerType>(Ty2);