1
0
Fork 0
mirror of https://github.com/beefytech/Beef.git synced 2025-06-10 04:22:20 +02:00

Lowering fix when lowered types are larger than source types

This commit is contained in:
Brian Fiete 2022-04-19 07:48:03 -07:00
parent 2652203597
commit 2de490fd59
4 changed files with 67 additions and 27 deletions

View file

@ -6883,12 +6883,27 @@ void BfExprEvaluator::PushArg(BfTypedValue argVal, SizedArrayImpl<BfIRValue>& ir
if ((!IsComptime()) && (!disableLowering) && (!isIntrinsic)) if ((!IsComptime()) && (!disableLowering) && (!isIntrinsic))
{ {
BfTypeCode loweredTypeCode = BfTypeCode_None; BfTypeCode loweredTypeCode = BfTypeCode_None;
BfTypeCode loweredTypeCode2 = BfTypeCode_None; BfTypeCode loweredTypeCode2 = BfTypeCode_None;
if (argVal.mType->GetLoweredType(BfTypeUsage_Parameter, &loweredTypeCode, &loweredTypeCode2)) if (argVal.mType->GetLoweredType(BfTypeUsage_Parameter, &loweredTypeCode, &loweredTypeCode2))
{ {
BfIRValue argPtrVal = argVal.mValue;
int loweredSize = mModule->mBfIRBuilder->GetSize(loweredTypeCode) + mModule->mBfIRBuilder->GetSize(loweredTypeCode2);
if (argVal.mType->mSize < loweredSize)
{
auto allocaVal = mModule->CreateAlloca(mModule->GetPrimitiveType(BfTypeCode_UInt8), true, NULL, mModule->GetConstValue(loweredSize));
mModule->mBfIRBuilder->SetAllocaAlignment(allocaVal,
BF_MAX(argVal.mType->mAlign,
BF_MAX(mModule->mBfIRBuilder->GetSize(loweredTypeCode), mModule->mBfIRBuilder->GetSize(loweredTypeCode2))));
auto castedPtr = mModule->mBfIRBuilder->CreateBitCast(allocaVal, mModule->mBfIRBuilder->MapType(mModule->CreatePointerType(argVal.mType)));
auto argIRVal = mModule->mBfIRBuilder->CreateAlignedLoad(argVal.mValue, argVal.mType->mAlign);
mModule->mBfIRBuilder->CreateAlignedStore(argIRVal, castedPtr, argVal.mType->mAlign);
argPtrVal = castedPtr;
}
auto primType = mModule->mBfIRBuilder->GetPrimitiveType(loweredTypeCode); auto primType = mModule->mBfIRBuilder->GetPrimitiveType(loweredTypeCode);
auto ptrType = mModule->mBfIRBuilder->GetPointerTo(primType); auto ptrType = mModule->mBfIRBuilder->GetPointerTo(primType);
BfIRValue primPtrVal = mModule->mBfIRBuilder->CreateBitCast(argVal.mValue, ptrType); BfIRValue primPtrVal = mModule->mBfIRBuilder->CreateBitCast(argPtrVal, ptrType);
auto primVal = mModule->mBfIRBuilder->CreateLoad(primPtrVal); auto primVal = mModule->mBfIRBuilder->CreateLoad(primPtrVal);
irArgs.push_back(primVal); irArgs.push_back(primVal);
@ -6903,9 +6918,8 @@ void BfExprEvaluator::PushArg(BfTypedValue argVal, SizedArrayImpl<BfIRValue>& ir
primPtrVal2 = mModule->mBfIRBuilder->CreateBitCast(mModule->mBfIRBuilder->CreateInBoundsGEP(primPtrVal, 1), ptrType2); primPtrVal2 = mModule->mBfIRBuilder->CreateBitCast(mModule->mBfIRBuilder->CreateInBoundsGEP(primPtrVal, 1), ptrType2);
auto primVal2 = mModule->mBfIRBuilder->CreateLoad(primPtrVal2); auto primVal2 = mModule->mBfIRBuilder->CreateLoad(primPtrVal2);
irArgs.push_back(primVal2); irArgs.Add(primVal2);
} }
return; return;
} }
} }
@ -6920,7 +6934,7 @@ void BfExprEvaluator::PushArg(BfTypedValue argVal, SizedArrayImpl<BfIRValue>& ir
} }
else else
argVal = mModule->LoadValue(argVal); argVal = mModule->LoadValue(argVal);
irArgs.push_back(argVal.mValue); irArgs.Add(argVal.mValue);
} }
} }

View file

@ -302,15 +302,15 @@ void BfIRConstHolder::FixTypeCode(BfTypeCode& typeCode)
} }
} }
int BfIRConstHolder::GetSize(BfTypeCode typeCode) int BfIRConstHolder::GetSize(BfTypeCode typeCode, int ptrSize)
{ {
switch (typeCode) switch (typeCode)
{ {
case BfTypeCode_None: return 0; case BfTypeCode_None: return 0;
case BfTypeCode_CharPtr: return mModule->mSystem->mPtrSize; case BfTypeCode_CharPtr: return ptrSize;
case BfTypeCode_StringId: return 4; case BfTypeCode_StringId: return 4;
case BfTypeCode_Pointer: return mModule->mSystem->mPtrSize; case BfTypeCode_Pointer: return ptrSize;
case BfTypeCode_NullPtr: return mModule->mSystem->mPtrSize; case BfTypeCode_NullPtr: return ptrSize;
case BfTypeCode_Self: return 0; case BfTypeCode_Self: return 0;
case BfTypeCode_Dot: return 0; case BfTypeCode_Dot: return 0;
case BfTypeCode_Var: return 0; case BfTypeCode_Var: return 0;
@ -334,8 +334,8 @@ int BfIRConstHolder::GetSize(BfTypeCode typeCode)
case BfTypeCode_UInt64: return 8; case BfTypeCode_UInt64: return 8;
case BfTypeCode_Int128: return 16; case BfTypeCode_Int128: return 16;
case BfTypeCode_UInt128: return 16; case BfTypeCode_UInt128: return 16;
case BfTypeCode_IntPtr: return mModule->mSystem->mPtrSize; case BfTypeCode_IntPtr: return ptrSize;
case BfTypeCode_UIntPtr: return mModule->mSystem->mPtrSize; case BfTypeCode_UIntPtr: return ptrSize;
case BfTypeCode_IntUnknown: return 0; case BfTypeCode_IntUnknown: return 0;
case BfTypeCode_UIntUnknown: return 0; case BfTypeCode_UIntUnknown: return 0;
case BfTypeCode_Char8: return 1; case BfTypeCode_Char8: return 1;
@ -344,25 +344,30 @@ int BfIRConstHolder::GetSize(BfTypeCode typeCode)
case BfTypeCode_Float: return 4; case BfTypeCode_Float: return 4;
case BfTypeCode_Double: return 8; case BfTypeCode_Double: return 8;
case BfTypeCode_Float2: return 8; case BfTypeCode_Float2: return 8;
case BfTypeCode_Object: return mModule->mSystem->mPtrSize; case BfTypeCode_Object: return ptrSize;
case BfTypeCode_Interface: return mModule->mSystem->mPtrSize; case BfTypeCode_Interface: return ptrSize;
case BfTypeCode_Struct: return 0; case BfTypeCode_Struct: return 0;
case BfTypeCode_Enum: return 0; case BfTypeCode_Enum: return 0;
case BfTypeCode_TypeAlias: return 0; case BfTypeCode_TypeAlias: return 0;
case BfTypeCode_Extension: return 0; case BfTypeCode_Extension: return 0;
case BfTypeCode_FloatX2: return 4*2; case BfTypeCode_FloatX2: return 4 * 2;
case BfTypeCode_FloatX3: return 4*3; case BfTypeCode_FloatX3: return 4 * 3;
case BfTypeCode_FloatX4: return 4*4; case BfTypeCode_FloatX4: return 4 * 4;
case BfTypeCode_DoubleX2: return 8*2; case BfTypeCode_DoubleX2: return 8 * 2;
case BfTypeCode_DoubleX3: return 8*3; case BfTypeCode_DoubleX3: return 8 * 3;
case BfTypeCode_DoubleX4: return 8*4; case BfTypeCode_DoubleX4: return 8 * 4;
case BfTypeCode_Int64X2: return 8*2; case BfTypeCode_Int64X2: return 8 * 2;
case BfTypeCode_Int64X3: return 8*3; case BfTypeCode_Int64X3: return 8 * 3;
case BfTypeCode_Int64X4: return 8*4; case BfTypeCode_Int64X4: return 8 * 4;
default: return 0; default: return 0;
} }
} }
int BfIRConstHolder::GetSize(BfTypeCode typeCode)
{
return GetSize(typeCode, mModule->mSystem->mPtrSize);
}
bool BfIRConstHolder::IsInt(BfTypeCode typeCode) bool BfIRConstHolder::IsInt(BfTypeCode typeCode)
{ {
return (typeCode >= BfTypeCode_Int8) && (typeCode <= BfTypeCode_Char32); return (typeCode >= BfTypeCode_Int8) && (typeCode <= BfTypeCode_Char32);

View file

@ -932,6 +932,7 @@ public:
public: public:
void FixTypeCode(BfTypeCode& typeCode); void FixTypeCode(BfTypeCode& typeCode);
int GetSize(BfTypeCode typeCode); int GetSize(BfTypeCode typeCode);
static int GetSize(BfTypeCode typeCode, int ptrSize);
static bool IsInt(BfTypeCode typeCode); static bool IsInt(BfTypeCode typeCode);
static bool IsChar(BfTypeCode typeCode); static bool IsChar(BfTypeCode typeCode);
static bool IsIntable(BfTypeCode typeCode); static bool IsIntable(BfTypeCode typeCode);

View file

@ -20313,19 +20313,32 @@ void BfModule::ProcessMethod(BfMethodInstance* methodInstance, bool isInlineDup,
} }
else else
{ {
bool handled = false; bool handled = false;
if (paramVar->mIsLowered) if (paramVar->mIsLowered)
{ {
BfTypeCode loweredTypeCode = BfTypeCode_None; BfTypeCode loweredTypeCode = BfTypeCode_None;
BfTypeCode loweredTypeCode2 = BfTypeCode_None; BfTypeCode loweredTypeCode2 = BfTypeCode_None;
if (paramVar->mResolvedType->GetLoweredType(BfTypeUsage_Parameter, &loweredTypeCode, &loweredTypeCode2)) if (paramVar->mResolvedType->GetLoweredType(BfTypeUsage_Parameter, &loweredTypeCode, &loweredTypeCode2))
{ {
BfIRValue targetAddr = paramVar->mAddr;
bool isTempTarget = false;
int loweredSize = mBfIRBuilder->GetSize(loweredTypeCode) + mBfIRBuilder->GetSize(loweredTypeCode2);
if (paramVar->mResolvedType->mSize < loweredSize)
{
isTempTarget = true;
targetAddr = CreateAlloca(GetPrimitiveType(BfTypeCode_Int8), true, NULL, GetConstValue(loweredSize));
mBfIRBuilder->SetAllocaAlignment(targetAddr,
BF_MAX(paramVar->mResolvedType->mAlign,
BF_MAX(mBfIRBuilder->GetSize(loweredTypeCode), mBfIRBuilder->GetSize(loweredTypeCode2))));
}
// We have a lowered type coming in, so we have to cast the .addr before storing // We have a lowered type coming in, so we have to cast the .addr before storing
auto primType = mBfIRBuilder->GetPrimitiveType(loweredTypeCode); auto primType = mBfIRBuilder->GetPrimitiveType(loweredTypeCode);
auto primPtrType = mBfIRBuilder->GetPointerTo(primType); auto primPtrType = mBfIRBuilder->GetPointerTo(primType);
auto primPtrVal = mBfIRBuilder->CreateBitCast(paramVar->mAddr, primPtrType); auto primPtrVal = mBfIRBuilder->CreateBitCast(targetAddr, primPtrType);
mBfIRBuilder->CreateAlignedStore(paramVar->mValue, primPtrVal, mCurTypeInstance->mAlign); mBfIRBuilder->CreateAlignedStore(paramVar->mValue, primPtrVal, mCurTypeInstance->mAlign);
if (loweredTypeCode2 != BfTypeCode_None) if (loweredTypeCode2 != BfTypeCode_None)
{ {
auto primType2 = mBfIRBuilder->GetPrimitiveType(loweredTypeCode2); auto primType2 = mBfIRBuilder->GetPrimitiveType(loweredTypeCode2);
@ -20336,12 +20349,19 @@ void BfModule::ProcessMethod(BfMethodInstance* methodInstance, bool isInlineDup,
else else
primPtrVal2 = mBfIRBuilder->CreateBitCast(mBfIRBuilder->CreateInBoundsGEP(primPtrVal, 1), primPtrType2); primPtrVal2 = mBfIRBuilder->CreateBitCast(mBfIRBuilder->CreateInBoundsGEP(primPtrVal, 1), primPtrType2);
mBfIRBuilder->CreateStore(mBfIRBuilder->GetArgument(argIdx + 1), primPtrVal2); mBfIRBuilder->CreateStore(mBfIRBuilder->GetArgument(argIdx + 1), primPtrVal2);
}
if (isTempTarget)
{
auto castedTempPtr = mBfIRBuilder->CreateBitCast(targetAddr, mBfIRBuilder->MapType(CreatePointerType(paramVar->mResolvedType)));
auto tempVal = mBfIRBuilder->CreateAlignedLoad(castedTempPtr, paramVar->mResolvedType->mAlign);
mBfIRBuilder->CreateAlignedStore(tempVal, paramVar->mAddr, paramVar->mResolvedType->mAlign);
} }
// We don't want to allow directly using value // We don't want to allow directly using value
paramVar->mValue = BfIRValue(); paramVar->mValue = BfIRValue();
handled = true; handled = true;
} }
else else
{ {
BF_ASSERT("Expected lowered"); BF_ASSERT("Expected lowered");