From 2de490fd5914e2820ecc878ebf1775e04ea7f9a4 Mon Sep 17 00:00:00 2001 From: Brian Fiete Date: Tue, 19 Apr 2022 07:48:03 -0700 Subject: [PATCH] Lowering fix when lowered types are larger than source types --- IDEHelper/Compiler/BfExprEvaluator.cpp | 24 ++++++++++++---- IDEHelper/Compiler/BfIRBuilder.cpp | 39 +++++++++++++++----------- IDEHelper/Compiler/BfIRBuilder.h | 1 + IDEHelper/Compiler/BfModule.cpp | 30 ++++++++++++++++---- 4 files changed, 67 insertions(+), 27 deletions(-) diff --git a/IDEHelper/Compiler/BfExprEvaluator.cpp b/IDEHelper/Compiler/BfExprEvaluator.cpp index e39accf2..54cb63f3 100644 --- a/IDEHelper/Compiler/BfExprEvaluator.cpp +++ b/IDEHelper/Compiler/BfExprEvaluator.cpp @@ -6883,12 +6883,27 @@ void BfExprEvaluator::PushArg(BfTypedValue argVal, SizedArrayImpl& ir if ((!IsComptime()) && (!disableLowering) && (!isIntrinsic)) { BfTypeCode loweredTypeCode = BfTypeCode_None; - BfTypeCode loweredTypeCode2 = BfTypeCode_None; + BfTypeCode loweredTypeCode2 = BfTypeCode_None; 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 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); irArgs.push_back(primVal); @@ -6903,9 +6918,8 @@ void BfExprEvaluator::PushArg(BfTypedValue argVal, SizedArrayImpl& ir primPtrVal2 = mModule->mBfIRBuilder->CreateBitCast(mModule->mBfIRBuilder->CreateInBoundsGEP(primPtrVal, 1), ptrType2); auto primVal2 = mModule->mBfIRBuilder->CreateLoad(primPtrVal2); - irArgs.push_back(primVal2); + irArgs.Add(primVal2); } - return; } } @@ -6920,7 +6934,7 @@ void BfExprEvaluator::PushArg(BfTypedValue argVal, SizedArrayImpl& ir } else argVal = mModule->LoadValue(argVal); - irArgs.push_back(argVal.mValue); + irArgs.Add(argVal.mValue); } } diff --git a/IDEHelper/Compiler/BfIRBuilder.cpp b/IDEHelper/Compiler/BfIRBuilder.cpp index 412d44b9..2a5fed4f 100644 --- a/IDEHelper/Compiler/BfIRBuilder.cpp +++ b/IDEHelper/Compiler/BfIRBuilder.cpp @@ -302,15 +302,15 @@ void BfIRConstHolder::FixTypeCode(BfTypeCode& typeCode) } } -int BfIRConstHolder::GetSize(BfTypeCode typeCode) +int BfIRConstHolder::GetSize(BfTypeCode typeCode, int ptrSize) { switch (typeCode) { case BfTypeCode_None: return 0; - case BfTypeCode_CharPtr: return mModule->mSystem->mPtrSize; + case BfTypeCode_CharPtr: return ptrSize; case BfTypeCode_StringId: return 4; - case BfTypeCode_Pointer: return mModule->mSystem->mPtrSize; - case BfTypeCode_NullPtr: return mModule->mSystem->mPtrSize; + case BfTypeCode_Pointer: return ptrSize; + case BfTypeCode_NullPtr: return ptrSize; case BfTypeCode_Self: return 0; case BfTypeCode_Dot: return 0; case BfTypeCode_Var: return 0; @@ -334,8 +334,8 @@ int BfIRConstHolder::GetSize(BfTypeCode typeCode) case BfTypeCode_UInt64: return 8; case BfTypeCode_Int128: return 16; case BfTypeCode_UInt128: return 16; - case BfTypeCode_IntPtr: return mModule->mSystem->mPtrSize; - case BfTypeCode_UIntPtr: return mModule->mSystem->mPtrSize; + case BfTypeCode_IntPtr: return ptrSize; + case BfTypeCode_UIntPtr: return ptrSize; case BfTypeCode_IntUnknown: return 0; case BfTypeCode_UIntUnknown: return 0; case BfTypeCode_Char8: return 1; @@ -344,25 +344,30 @@ int BfIRConstHolder::GetSize(BfTypeCode typeCode) case BfTypeCode_Float: return 4; case BfTypeCode_Double: return 8; case BfTypeCode_Float2: return 8; - case BfTypeCode_Object: return mModule->mSystem->mPtrSize; - case BfTypeCode_Interface: return mModule->mSystem->mPtrSize; + case BfTypeCode_Object: return ptrSize; + case BfTypeCode_Interface: return ptrSize; case BfTypeCode_Struct: return 0; case BfTypeCode_Enum: return 0; case BfTypeCode_TypeAlias: return 0; case BfTypeCode_Extension: return 0; - case BfTypeCode_FloatX2: return 4*2; - case BfTypeCode_FloatX3: return 4*3; - case BfTypeCode_FloatX4: return 4*4; - case BfTypeCode_DoubleX2: return 8*2; - case BfTypeCode_DoubleX3: return 8*3; - case BfTypeCode_DoubleX4: return 8*4; - case BfTypeCode_Int64X2: return 8*2; - case BfTypeCode_Int64X3: return 8*3; - case BfTypeCode_Int64X4: return 8*4; + case BfTypeCode_FloatX2: return 4 * 2; + case BfTypeCode_FloatX3: return 4 * 3; + case BfTypeCode_FloatX4: return 4 * 4; + case BfTypeCode_DoubleX2: return 8 * 2; + case BfTypeCode_DoubleX3: return 8 * 3; + case BfTypeCode_DoubleX4: return 8 * 4; + case BfTypeCode_Int64X2: return 8 * 2; + case BfTypeCode_Int64X3: return 8 * 3; + case BfTypeCode_Int64X4: return 8 * 4; default: return 0; } } +int BfIRConstHolder::GetSize(BfTypeCode typeCode) +{ + return GetSize(typeCode, mModule->mSystem->mPtrSize); +} + bool BfIRConstHolder::IsInt(BfTypeCode typeCode) { return (typeCode >= BfTypeCode_Int8) && (typeCode <= BfTypeCode_Char32); diff --git a/IDEHelper/Compiler/BfIRBuilder.h b/IDEHelper/Compiler/BfIRBuilder.h index 31ca43ed..ec73a410 100644 --- a/IDEHelper/Compiler/BfIRBuilder.h +++ b/IDEHelper/Compiler/BfIRBuilder.h @@ -932,6 +932,7 @@ public: public: void FixTypeCode(BfTypeCode& typeCode); int GetSize(BfTypeCode typeCode); + static int GetSize(BfTypeCode typeCode, int ptrSize); static bool IsInt(BfTypeCode typeCode); static bool IsChar(BfTypeCode typeCode); static bool IsIntable(BfTypeCode typeCode); diff --git a/IDEHelper/Compiler/BfModule.cpp b/IDEHelper/Compiler/BfModule.cpp index 2d48e1db..490aab5a 100644 --- a/IDEHelper/Compiler/BfModule.cpp +++ b/IDEHelper/Compiler/BfModule.cpp @@ -20313,19 +20313,32 @@ void BfModule::ProcessMethod(BfMethodInstance* methodInstance, bool isInlineDup, } else { - bool handled = false; + bool handled = false; if (paramVar->mIsLowered) { BfTypeCode loweredTypeCode = BfTypeCode_None; - BfTypeCode loweredTypeCode2 = BfTypeCode_None; + BfTypeCode loweredTypeCode2 = BfTypeCode_None; 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 auto primType = mBfIRBuilder->GetPrimitiveType(loweredTypeCode); 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); - + if (loweredTypeCode2 != BfTypeCode_None) { auto primType2 = mBfIRBuilder->GetPrimitiveType(loweredTypeCode2); @@ -20336,12 +20349,19 @@ void BfModule::ProcessMethod(BfMethodInstance* methodInstance, bool isInlineDup, else primPtrVal2 = mBfIRBuilder->CreateBitCast(mBfIRBuilder->CreateInBoundsGEP(primPtrVal, 1), primPtrType2); 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 paramVar->mValue = BfIRValue(); handled = true; - } + } else { BF_ASSERT("Expected lowered");