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

Fixed array alloca with non-aligned structs

This commit is contained in:
Brian Fiete 2022-04-26 11:41:34 -07:00
parent 259f50d612
commit f54980400e
3 changed files with 68 additions and 22 deletions

View file

@ -16126,7 +16126,7 @@ void BeMCContext::Generate(BeFunction* function)
mDbgPreferredRegs[32] = X64Reg_R8;*/ mDbgPreferredRegs[32] = X64Reg_R8;*/
//mDbgPreferredRegs[8] = X64Reg_RAX; //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 == "?MethodA@TestProgram@BeefTest@bf@@CAXXZ");
// || (function->mName == "?Hey@Blurg@bf@@SAXXZ") // || (function->mName == "?Hey@Blurg@bf@@SAXXZ")
// ; // ;
@ -16748,6 +16748,8 @@ void BeMCContext::Generate(BeFunction* function)
bool doPtrCast = false; bool doPtrCast = false;
if (castedInst->mArraySize != NULL) if (castedInst->mArraySize != NULL)
{ {
mcSize = BeMCOperand::FromImmediate(castedInst->mType->GetStride());
auto mcArraySize = GetOperand(castedInst->mArraySize); auto mcArraySize = GetOperand(castedInst->mArraySize);
if (mcArraySize.IsImmediate()) if (mcArraySize.IsImmediate())
{ {

View file

@ -197,6 +197,7 @@ static const BuiltinEntry gIntrinEntries[] =
}; };
#define CMD_PARAM(ty, name) ty name; Read(name); #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); BF_STATIC_ASSERT(BF_ARRAY_COUNT(gIntrinEntries) == BfIRIntrinsic_COUNT);
template <typename T> template <typename T>
@ -654,6 +655,14 @@ void BfIRCodeGen::SetResult(int id, llvm::Value* value)
mResults.TryAdd(id, entry); 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) void BfIRCodeGen::SetResult(int id, llvm::Type* type)
{ {
BfIRCodeGenEntry entry; BfIRCodeGenEntry entry;
@ -828,7 +837,7 @@ void BfIRCodeGen::Read(llvm::FunctionType*& llvmType)
llvmType = (llvm::FunctionType*)result.mLLVMType; 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(); BfIRParamType paramType = (BfIRParamType)mStream->Read();
if (paramType == BfIRParamType_None) if (paramType == BfIRParamType_None)
@ -976,7 +985,7 @@ void BfIRCodeGen::Read(llvm::Value*& llvmValue, BfIRCodeGenEntry** codeGenEntry,
BfIRTypeEntry* typeEntry = NULL; BfIRTypeEntry* typeEntry = NULL;
llvm::Type* type = NULL; llvm::Type* type = NULL;
Read(type, &typeEntry); Read(type, &typeEntry);
if ((wantSizeAligned) && (typeEntry != NULL)) if ((sizeAlignKind == BfIRSizeAlignKind_Aligned) && (typeEntry != NULL))
llvmValue = llvm::ConstantAggregateZero::get(GetSizeAlignedType(typeEntry)); llvmValue = llvm::ConstantAggregateZero::get(GetSizeAlignedType(typeEntry));
else else
llvmValue = llvm::ConstantAggregateZero::get(type); llvmValue = llvm::ConstantAggregateZero::get(type);
@ -995,7 +1004,7 @@ void BfIRCodeGen::Read(llvm::Value*& llvmValue, BfIRCodeGenEntry** codeGenEntry,
llvm::Type* type = NULL; llvm::Type* type = NULL;
Read(type, &typeEntry); Read(type, &typeEntry);
CmdParamVec<llvm::Constant*> values; CmdParamVec<llvm::Constant*> values;
Read(values, type->isArrayTy()); Read(values, type->isArrayTy() ? BfIRSizeAlignKind_Aligned : BfIRSizeAlignKind_Original);
if (auto arrayType = llvm::dyn_cast<llvm::ArrayType>(type)) if (auto arrayType = llvm::dyn_cast<llvm::ArrayType>(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<llvm::StructType>(GetSizeAlignedType(typeEntry)); auto alignedType = llvm::dyn_cast<llvm::StructType>(GetSizeAlignedType(typeEntry));
if (type != alignedType) 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<llvm::PointerType>(llvmValue->getType()))
{
if (mAlignedTypeToNormalType.TryGetValue(ptrType->getElementType(), &normalType))
{
llvmValue = mIRBuilder->CreateBitCast(llvmValue, normalType->getPointerTo());
return;
}
}
}
BF_ASSERT(result.mKind == BfIRCodeGenEntryKind_LLVMValue); BF_ASSERT(result.mKind == BfIRCodeGenEntryKind_LLVMValue);
llvmValue = result.mLLVMValue; llvmValue = result.mLLVMValue;
} }
} }
void BfIRCodeGen::Read(llvm::Constant*& llvmConstant, bool wantSizeAligned) void BfIRCodeGen::Read(llvm::Constant*& llvmConstant, BfIRSizeAlignKind sizeAlignKind)
{ {
llvm::Value* value; llvm::Value* value;
Read(value, NULL, wantSizeAligned); Read(value, NULL, sizeAlignKind);
if (value == NULL) if (value == NULL)
{ {
llvmConstant = NULL; llvmConstant = NULL;
@ -1999,7 +2025,7 @@ void BfIRCodeGen::HandleNextCmd()
break; break;
case BfIRCmd_SetName: case BfIRCmd_SetName:
{ {
CMD_PARAM(llvm::Value*, val); CMD_PARAM_NOTRANS(llvm::Value*, val);
CMD_PARAM(String, name); CMD_PARAM(String, name);
val->setName(name.c_str()); val->setName(name.c_str());
} }
@ -2423,12 +2449,21 @@ void BfIRCodeGen::HandleNextCmd()
{ {
CMD_PARAM(llvm::Type*, type); CMD_PARAM(llvm::Type*, type);
CMD_PARAM(llvm::Value*, arraySize); 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; break;
case BfIRCmd_SetAllocaAlignment: case BfIRCmd_SetAllocaAlignment:
{ {
CMD_PARAM(llvm::Value*, val); CMD_PARAM_NOTRANS(llvm::Value*, val);
CMD_PARAM(int, alignment); CMD_PARAM(int, alignment);
auto inst = llvm::dyn_cast<llvm::AllocaInst>(val); auto inst = llvm::dyn_cast<llvm::AllocaInst>(val);
inst->setAlignment(llvm::Align(alignment)); inst->setAlignment(llvm::Align(alignment));
@ -2436,25 +2471,25 @@ void BfIRCodeGen::HandleNextCmd()
break; break;
case BfIRCmd_SetAllocaNoChkStkHint: case BfIRCmd_SetAllocaNoChkStkHint:
{ {
CMD_PARAM(llvm::Value*, val); CMD_PARAM_NOTRANS(llvm::Value*, val);
// LLVM does not support this // LLVM does not support this
} }
break; break;
case BfIRCmd_LifetimeStart: case BfIRCmd_LifetimeStart:
{ {
CMD_PARAM(llvm::Value*, val); CMD_PARAM_NOTRANS(llvm::Value*, val);
SetResult(curId, mIRBuilder->CreateLifetimeStart(val)); SetResult(curId, mIRBuilder->CreateLifetimeStart(val));
} }
break; break;
case BfIRCmd_LifetimeEnd: case BfIRCmd_LifetimeEnd:
{ {
CMD_PARAM(llvm::Value*, val); CMD_PARAM_NOTRANS(llvm::Value*, val);
SetResult(curId, mIRBuilder->CreateLifetimeEnd(val)); SetResult(curId, mIRBuilder->CreateLifetimeEnd(val));
} }
break; break;
case BfIRCmd_LifetimeExtend: case BfIRCmd_LifetimeExtend:
{ {
CMD_PARAM(llvm::Value*, val); CMD_PARAM_NOTRANS(llvm::Value*, val);
} }
break; break;
case BfIRCmd_Load: case BfIRCmd_Load:
@ -3972,7 +4007,7 @@ void BfIRCodeGen::HandleNextCmd()
break; break;
case BfIRCmd_ClearDebugLocationInst: case BfIRCmd_ClearDebugLocationInst:
{ {
CMD_PARAM(llvm::Value*, instValue); CMD_PARAM_NOTRANS(llvm::Value*, instValue);
BF_ASSERT(llvm::isa<llvm::Instruction>(instValue)); BF_ASSERT(llvm::isa<llvm::Instruction>(instValue));
((llvm::Instruction*)instValue)->setDebugLoc(llvm::DebugLoc()); ((llvm::Instruction*)instValue)->setDebugLoc(llvm::DebugLoc());
} }
@ -3993,7 +4028,7 @@ void BfIRCodeGen::HandleNextCmd()
break; break;
case BfIRCmd_UpdateDebugLocation: case BfIRCmd_UpdateDebugLocation:
{ {
CMD_PARAM(llvm::Value*, instValue); CMD_PARAM_NOTRANS(llvm::Value*, instValue);
BF_ASSERT(llvm::isa<llvm::Instruction>(instValue)); BF_ASSERT(llvm::isa<llvm::Instruction>(instValue));
((llvm::Instruction*)instValue)->setDebugLoc(mIRBuilder->getCurrentDebugLocation()); ((llvm::Instruction*)instValue)->setDebugLoc(mIRBuilder->getCurrentDebugLocation());
} }

View file

@ -29,6 +29,7 @@ enum BfIRCodeGenEntryKind
{ {
BfIRCodeGenEntryKind_None, BfIRCodeGenEntryKind_None,
BfIRCodeGenEntryKind_LLVMValue, BfIRCodeGenEntryKind_LLVMValue,
BfIRCodeGenEntryKind_LLVMValue_Aligned,
BfIRCodeGenEntryKind_LLVMType, BfIRCodeGenEntryKind_LLVMType,
BfIRCodeGenEntryKind_LLVMBasicBlock, BfIRCodeGenEntryKind_LLVMBasicBlock,
BfIRCodeGenEntryKind_LLVMMetadata, BfIRCodeGenEntryKind_LLVMMetadata,
@ -82,6 +83,13 @@ public:
} }
}; };
enum BfIRSizeAlignKind
{
BfIRSizeAlignKind_NoTransform,
BfIRSizeAlignKind_Original,
BfIRSizeAlignKind_Aligned,
};
class BfIRCodeGen : public BfIRCodeGenBase class BfIRCodeGen : public BfIRCodeGenBase
{ {
public: public:
@ -132,6 +140,7 @@ public:
BfIRTypeEntry& GetTypeEntry(int typeId); BfIRTypeEntry& GetTypeEntry(int typeId);
BfIRTypeEntry* GetTypeEntry(llvm::Type* type); BfIRTypeEntry* GetTypeEntry(llvm::Type* type);
void SetResult(int id, llvm::Value* value); 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::Type* value);
void SetResult(int id, llvm::BasicBlock* value); void SetResult(int id, llvm::BasicBlock* value);
void SetResult(int id, llvm::MDNode* value); void SetResult(int id, llvm::MDNode* value);
@ -168,8 +177,8 @@ public:
void Read(BfIRTypeEntry*& type); void Read(BfIRTypeEntry*& type);
void Read(llvm::Type*& llvmType, BfIRTypeEntry** outTypeEntry = NULL); void Read(llvm::Type*& llvmType, BfIRTypeEntry** outTypeEntry = NULL);
void Read(llvm::FunctionType*& llvmType); void Read(llvm::FunctionType*& llvmType);
void Read(llvm::Value*& llvmValue, BfIRCodeGenEntry** codeGenEntry = NULL, bool wantSizeAligned = false); void Read(llvm::Value*& llvmValue, BfIRCodeGenEntry** codeGenEntry = NULL, BfIRSizeAlignKind sizeAlignKind = BfIRSizeAlignKind_Original);
void Read(llvm::Constant*& llvmConstant, bool wantSizeAligned = false); void Read(llvm::Constant*& llvmConstant, BfIRSizeAlignKind sizeAlignKind = BfIRSizeAlignKind_Original);
void Read(llvm::Function*& llvmFunc); void Read(llvm::Function*& llvmFunc);
void Read(llvm::BasicBlock*& llvmBlock); void Read(llvm::BasicBlock*& llvmBlock);
void Read(llvm::MDNode*& llvmMD); void Read(llvm::MDNode*& llvmMD);
@ -187,24 +196,24 @@ public:
} }
} }
void Read(llvm::SmallVectorImpl<llvm::Value*>& vec, bool wantSizeAligned = false) void Read(llvm::SmallVectorImpl<llvm::Value*>& vec, BfIRSizeAlignKind sizeAlignKind = BfIRSizeAlignKind_Original)
{ {
int len = (int)ReadSLEB128(); int len = (int)ReadSLEB128();
for (int i = 0; i < len; i++) for (int i = 0; i < len; i++)
{ {
llvm::Value* result; llvm::Value* result;
Read(result, NULL, wantSizeAligned); Read(result, NULL, sizeAlignKind);
vec.push_back(result); vec.push_back(result);
} }
} }
void Read(llvm::SmallVectorImpl<llvm::Constant*>& vec, bool wantSizeAligned = false) void Read(llvm::SmallVectorImpl<llvm::Constant*>& vec, BfIRSizeAlignKind sizeAlignKind = BfIRSizeAlignKind_Original)
{ {
int len = (int)ReadSLEB128(); int len = (int)ReadSLEB128();
for (int i = 0; i < len; i++) for (int i = 0; i < len; i++)
{ {
llvm::Constant* result; llvm::Constant* result;
Read(result, wantSizeAligned); Read(result, sizeAlignKind);
vec.push_back(result); vec.push_back(result);
} }
} }