diff --git a/IDEHelper/Beef/BfCommon.h b/IDEHelper/Beef/BfCommon.h index 319b815d..d211f748 100644 --- a/IDEHelper/Beef/BfCommon.h +++ b/IDEHelper/Beef/BfCommon.h @@ -108,6 +108,7 @@ public: T& operator[](int idx) const { + BF_ASSERT((uint)idx < (uint)mSize); return mVals[idx]; } diff --git a/IDEHelper/Compiler/BfIRBuilder.cpp b/IDEHelper/Compiler/BfIRBuilder.cpp index 2f57aed7..c31df9cd 100644 --- a/IDEHelper/Compiler/BfIRBuilder.cpp +++ b/IDEHelper/Compiler/BfIRBuilder.cpp @@ -344,6 +344,35 @@ bool BfIRConstHolder::TryGetBool(BfIRValue id, bool& boolVal) return false; } +int BfIRConstHolder::IsZero(BfIRValue value) +{ + auto constant = GetConstant(value); + if (constant == NULL) + return -1; + + if ((constant->mTypeCode >= BfTypeCode_Boolean) && (constant->mTypeCode <= BfTypeCode_Double)) + { + return (constant->mUInt64 == 0) ? 1 : 0; + } + + if (constant->mConstType == BfConstType_AggZero) + return 1; + + if (constant->mConstType == BfConstType_Array) + { + auto constArr = (BfConstantArray*)constant; + for (int i = 0; i < constArr->mValues.mSize; i++) + { + int elemResult = IsZero(constArr->mValues[i]); + if (elemResult != 1) + return elemResult; + } + return 1; + } + + return -1; +} + int BfIRConstHolder::CheckConstEquality(BfIRValue lhs, BfIRValue rhs) { auto constLHS = GetConstant(lhs); @@ -358,10 +387,37 @@ int BfIRConstHolder::CheckConstEquality(BfIRValue lhs, BfIRValue rhs) if (constRHS->mConstType == BfConstType_BitCast) return CheckConstEquality(lhs, BfIRValue(BfIRValueFlags_Const, ((BfConstantBitCast*)constRHS)->mTarget)); - if ((constLHS->mConstType == BfConstType_GlobalVar) && - (constRHS->mConstType == BfConstType_GlobalVar)) + int lhsZero = IsZero(lhs); + if (lhsZero != -1) { - return (constLHS == constRHS) ? 1 : 0; + int rhsZero = IsZero(rhs); + if (rhsZero != -1) + return (lhsZero == rhsZero) ? 1 : 0; + } + + if (constLHS->mTypeCode != constRHS->mTypeCode) + return -1; + + if ((constLHS->mTypeCode >= BfTypeCode_Boolean) && (constLHS->mTypeCode <= BfTypeCode_Double)) + { + return (constLHS->mUInt64 == constRHS->mUInt16) ? 1 : 0; + } + + if (constLHS->mConstType == BfConstType_Array) + { + auto arrayLHS = (BfConstantArray*)constLHS; + auto arrayRHS = (BfConstantArray*)constRHS; + + if (arrayLHS->mValues.mSize != arrayRHS->mValues.mSize) + return -1; + + for (int i = 0; i < arrayLHS->mValues.mSize; i++) + { + int elemResult = CheckConstEquality(arrayLHS->mValues[i], arrayRHS->mValues[i]); + if (elemResult != 1) + return elemResult; + } + return 1; } return -1; diff --git a/IDEHelper/Compiler/BfIRBuilder.h b/IDEHelper/Compiler/BfIRBuilder.h index 2a2c2414..24599442 100644 --- a/IDEHelper/Compiler/BfIRBuilder.h +++ b/IDEHelper/Compiler/BfIRBuilder.h @@ -830,6 +830,7 @@ public: BfConstant* GetConstantById(int id); BfConstant* GetConstant(BfIRValue id); bool TryGetBool(BfIRValue id, bool& boolVal); + int IsZero(BfIRValue val); int CheckConstEquality(BfIRValue lhs, BfIRValue rhs); // -1 = fail, 0 = false, 1 = true BfIRValue CreateConst(BfTypeCode typeCode, uint64 val);