From f54980400e1531822db7470203d5e81a271e71ab Mon Sep 17 00:00:00 2001 From: Brian Fiete Date: Tue, 26 Apr 2022 11:41:34 -0700 Subject: [PATCH] Fixed array alloca with non-aligned structs --- IDEHelper/Backend/BeMCContext.cpp | 4 +- IDEHelper/Compiler/BfIRCodeGen.cpp | 65 +++++++++++++++++++++++------- IDEHelper/Compiler/BfIRCodeGen.h | 21 +++++++--- 3 files changed, 68 insertions(+), 22 deletions(-) diff --git a/IDEHelper/Backend/BeMCContext.cpp b/IDEHelper/Backend/BeMCContext.cpp index 3257475b..60055735 100644 --- a/IDEHelper/Backend/BeMCContext.cpp +++ b/IDEHelper/Backend/BeMCContext.cpp @@ -16126,7 +16126,7 @@ void BeMCContext::Generate(BeFunction* function) mDbgPreferredRegs[32] = X64Reg_R8;*/ //mDbgPreferredRegs[8] = X64Reg_RAX; - //mDebugging = (function->mName == "?Test@TestProgram@BeefTest@bf@@AEAA_NXZ"); + //mDebugging = (function->mName == "?Main@TestProgram@BeefTest@bf@@CAXXZ"); // || (function->mName == "?MethodA@TestProgram@BeefTest@bf@@CAXXZ"); // || (function->mName == "?Hey@Blurg@bf@@SAXXZ") // ; @@ -16748,6 +16748,8 @@ void BeMCContext::Generate(BeFunction* function) bool doPtrCast = false; if (castedInst->mArraySize != NULL) { + mcSize = BeMCOperand::FromImmediate(castedInst->mType->GetStride()); + auto mcArraySize = GetOperand(castedInst->mArraySize); if (mcArraySize.IsImmediate()) { diff --git a/IDEHelper/Compiler/BfIRCodeGen.cpp b/IDEHelper/Compiler/BfIRCodeGen.cpp index 58b44e02..4f26bf2c 100644 --- a/IDEHelper/Compiler/BfIRCodeGen.cpp +++ b/IDEHelper/Compiler/BfIRCodeGen.cpp @@ -197,6 +197,7 @@ static const BuiltinEntry gIntrinEntries[] = }; #define CMD_PARAM(ty, name) ty name; Read(name); +#define CMD_PARAM_NOTRANS(ty, name) ty name; Read(name, NULL, BfIRSizeAlignKind_NoTransform); BF_STATIC_ASSERT(BF_ARRAY_COUNT(gIntrinEntries) == BfIRIntrinsic_COUNT); template @@ -654,6 +655,14 @@ void BfIRCodeGen::SetResult(int id, llvm::Value* value) mResults.TryAdd(id, entry); } +void BfIRCodeGen::SetResultAligned(int id, llvm::Value* value) +{ + BfIRCodeGenEntry entry; + entry.mKind = BfIRCodeGenEntryKind_LLVMValue_Aligned; + entry.mLLVMValue = value; + mResults.TryAdd(id, entry); +} + void BfIRCodeGen::SetResult(int id, llvm::Type* type) { BfIRCodeGenEntry entry; @@ -828,7 +837,7 @@ void BfIRCodeGen::Read(llvm::FunctionType*& llvmType) llvmType = (llvm::FunctionType*)result.mLLVMType; } -void BfIRCodeGen::Read(llvm::Value*& llvmValue, BfIRCodeGenEntry** codeGenEntry, bool wantSizeAligned) +void BfIRCodeGen::Read(llvm::Value*& llvmValue, BfIRCodeGenEntry** codeGenEntry, BfIRSizeAlignKind sizeAlignKind) { BfIRParamType paramType = (BfIRParamType)mStream->Read(); if (paramType == BfIRParamType_None) @@ -976,7 +985,7 @@ void BfIRCodeGen::Read(llvm::Value*& llvmValue, BfIRCodeGenEntry** codeGenEntry, BfIRTypeEntry* typeEntry = NULL; llvm::Type* type = NULL; Read(type, &typeEntry); - if ((wantSizeAligned) && (typeEntry != NULL)) + if ((sizeAlignKind == BfIRSizeAlignKind_Aligned) && (typeEntry != NULL)) llvmValue = llvm::ConstantAggregateZero::get(GetSizeAlignedType(typeEntry)); else llvmValue = llvm::ConstantAggregateZero::get(type); @@ -995,7 +1004,7 @@ void BfIRCodeGen::Read(llvm::Value*& llvmValue, BfIRCodeGenEntry** codeGenEntry, llvm::Type* type = NULL; Read(type, &typeEntry); CmdParamVec values; - Read(values, type->isArrayTy()); + Read(values, type->isArrayTy() ? BfIRSizeAlignKind_Aligned : BfIRSizeAlignKind_Original); if (auto arrayType = llvm::dyn_cast(type)) { @@ -1025,7 +1034,7 @@ void BfIRCodeGen::Read(llvm::Value*& llvmValue, BfIRCodeGenEntry** codeGenEntry, } } - if ((wantSizeAligned) && (typeEntry != NULL)) + if ((sizeAlignKind == BfIRSizeAlignKind_Aligned) && (typeEntry != NULL)) { auto alignedType = llvm::dyn_cast(GetSizeAlignedType(typeEntry)); if (type != alignedType) @@ -1153,15 +1162,32 @@ void BfIRCodeGen::Read(llvm::Value*& llvmValue, BfIRCodeGenEntry** codeGenEntry, } } + if (result.mKind == BfIRCodeGenEntryKind_LLVMValue_Aligned) + { + llvmValue = result.mLLVMValue; + if (sizeAlignKind != BfIRSizeAlignKind_Original) + return; + + llvm::Type* normalType = NULL; + if (auto ptrType = llvm::dyn_cast(llvmValue->getType())) + { + if (mAlignedTypeToNormalType.TryGetValue(ptrType->getElementType(), &normalType)) + { + llvmValue = mIRBuilder->CreateBitCast(llvmValue, normalType->getPointerTo()); + return; + } + } + } + BF_ASSERT(result.mKind == BfIRCodeGenEntryKind_LLVMValue); llvmValue = result.mLLVMValue; } } -void BfIRCodeGen::Read(llvm::Constant*& llvmConstant, bool wantSizeAligned) +void BfIRCodeGen::Read(llvm::Constant*& llvmConstant, BfIRSizeAlignKind sizeAlignKind) { llvm::Value* value; - Read(value, NULL, wantSizeAligned); + Read(value, NULL, sizeAlignKind); if (value == NULL) { llvmConstant = NULL; @@ -1999,7 +2025,7 @@ void BfIRCodeGen::HandleNextCmd() break; case BfIRCmd_SetName: { - CMD_PARAM(llvm::Value*, val); + CMD_PARAM_NOTRANS(llvm::Value*, val); CMD_PARAM(String, name); val->setName(name.c_str()); } @@ -2423,12 +2449,21 @@ void BfIRCodeGen::HandleNextCmd() { CMD_PARAM(llvm::Type*, type); CMD_PARAM(llvm::Value*, arraySize); - SetResult(curId, mIRBuilder->CreateAlloca(type, arraySize)); + + auto origType = type; + auto typeEntry = GetTypeEntry(type); + if (typeEntry != NULL) + type = GetSizeAlignedType(typeEntry); + + if (origType != type) + SetResultAligned(curId, mIRBuilder->CreateAlloca(type, arraySize)); + else + SetResult(curId, mIRBuilder->CreateAlloca(type, arraySize)); } break; case BfIRCmd_SetAllocaAlignment: { - CMD_PARAM(llvm::Value*, val); + CMD_PARAM_NOTRANS(llvm::Value*, val); CMD_PARAM(int, alignment); auto inst = llvm::dyn_cast(val); inst->setAlignment(llvm::Align(alignment)); @@ -2436,25 +2471,25 @@ void BfIRCodeGen::HandleNextCmd() break; case BfIRCmd_SetAllocaNoChkStkHint: { - CMD_PARAM(llvm::Value*, val); + CMD_PARAM_NOTRANS(llvm::Value*, val); // LLVM does not support this } break; case BfIRCmd_LifetimeStart: { - CMD_PARAM(llvm::Value*, val); + CMD_PARAM_NOTRANS(llvm::Value*, val); SetResult(curId, mIRBuilder->CreateLifetimeStart(val)); } break; case BfIRCmd_LifetimeEnd: { - CMD_PARAM(llvm::Value*, val); + CMD_PARAM_NOTRANS(llvm::Value*, val); SetResult(curId, mIRBuilder->CreateLifetimeEnd(val)); } break; case BfIRCmd_LifetimeExtend: { - CMD_PARAM(llvm::Value*, val); + CMD_PARAM_NOTRANS(llvm::Value*, val); } break; case BfIRCmd_Load: @@ -3972,7 +4007,7 @@ void BfIRCodeGen::HandleNextCmd() break; case BfIRCmd_ClearDebugLocationInst: { - CMD_PARAM(llvm::Value*, instValue); + CMD_PARAM_NOTRANS(llvm::Value*, instValue); BF_ASSERT(llvm::isa(instValue)); ((llvm::Instruction*)instValue)->setDebugLoc(llvm::DebugLoc()); } @@ -3993,7 +4028,7 @@ void BfIRCodeGen::HandleNextCmd() break; case BfIRCmd_UpdateDebugLocation: { - CMD_PARAM(llvm::Value*, instValue); + CMD_PARAM_NOTRANS(llvm::Value*, instValue); BF_ASSERT(llvm::isa(instValue)); ((llvm::Instruction*)instValue)->setDebugLoc(mIRBuilder->getCurrentDebugLocation()); } diff --git a/IDEHelper/Compiler/BfIRCodeGen.h b/IDEHelper/Compiler/BfIRCodeGen.h index 9a7c1428..049ca8d7 100644 --- a/IDEHelper/Compiler/BfIRCodeGen.h +++ b/IDEHelper/Compiler/BfIRCodeGen.h @@ -29,6 +29,7 @@ enum BfIRCodeGenEntryKind { BfIRCodeGenEntryKind_None, BfIRCodeGenEntryKind_LLVMValue, + BfIRCodeGenEntryKind_LLVMValue_Aligned, BfIRCodeGenEntryKind_LLVMType, BfIRCodeGenEntryKind_LLVMBasicBlock, BfIRCodeGenEntryKind_LLVMMetadata, @@ -82,6 +83,13 @@ public: } }; +enum BfIRSizeAlignKind +{ + BfIRSizeAlignKind_NoTransform, + BfIRSizeAlignKind_Original, + BfIRSizeAlignKind_Aligned, +}; + class BfIRCodeGen : public BfIRCodeGenBase { public: @@ -132,6 +140,7 @@ public: BfIRTypeEntry& GetTypeEntry(int typeId); BfIRTypeEntry* GetTypeEntry(llvm::Type* type); void SetResult(int id, llvm::Value* value); + void SetResultAligned(int id, llvm::Value* value); void SetResult(int id, llvm::Type* value); void SetResult(int id, llvm::BasicBlock* value); void SetResult(int id, llvm::MDNode* value); @@ -168,8 +177,8 @@ public: void Read(BfIRTypeEntry*& type); void Read(llvm::Type*& llvmType, BfIRTypeEntry** outTypeEntry = NULL); void Read(llvm::FunctionType*& llvmType); - void Read(llvm::Value*& llvmValue, BfIRCodeGenEntry** codeGenEntry = NULL, bool wantSizeAligned = false); - void Read(llvm::Constant*& llvmConstant, bool wantSizeAligned = false); + void Read(llvm::Value*& llvmValue, BfIRCodeGenEntry** codeGenEntry = NULL, BfIRSizeAlignKind sizeAlignKind = BfIRSizeAlignKind_Original); + void Read(llvm::Constant*& llvmConstant, BfIRSizeAlignKind sizeAlignKind = BfIRSizeAlignKind_Original); void Read(llvm::Function*& llvmFunc); void Read(llvm::BasicBlock*& llvmBlock); void Read(llvm::MDNode*& llvmMD); @@ -187,24 +196,24 @@ public: } } - void Read(llvm::SmallVectorImpl& vec, bool wantSizeAligned = false) + void Read(llvm::SmallVectorImpl& vec, BfIRSizeAlignKind sizeAlignKind = BfIRSizeAlignKind_Original) { int len = (int)ReadSLEB128(); for (int i = 0; i < len; i++) { llvm::Value* result; - Read(result, NULL, wantSizeAligned); + Read(result, NULL, sizeAlignKind); vec.push_back(result); } } - void Read(llvm::SmallVectorImpl& vec, bool wantSizeAligned = false) + void Read(llvm::SmallVectorImpl& vec, BfIRSizeAlignKind sizeAlignKind = BfIRSizeAlignKind_Original) { int len = (int)ReadSLEB128(); for (int i = 0; i < len; i++) { llvm::Constant* result; - Read(result, wantSizeAligned); + Read(result, sizeAlignKind); vec.push_back(result); } }