From 6b6914a373a0ef0c3ad6f557fa61f3771a867264 Mon Sep 17 00:00:00 2001 From: Roman Rusyaev Date: Wed, 6 Jul 2022 18:44:31 +0300 Subject: [PATCH 1/3] Fix 'dread' simplification Truncate union filed while 'dread' simplification to an appropriate size if it was written as int but is read as bit-field with smaller size. --- src/mapleall/maple_ir/include/global_tables.h | 1 + src/mapleall/maple_ir/src/global_tables.cpp | 7 +++ src/mapleall/maple_util/include/mpl_int_val.h | 13 ++++ src/mapleall/mpl2mpl/src/simplify.cpp | 61 ++++++++++++++++--- 4 files changed, 74 insertions(+), 8 deletions(-) diff --git a/src/mapleall/maple_ir/include/global_tables.h b/src/mapleall/maple_ir/include/global_tables.h index 0eef3dddc6..2c4ba0c363 100644 --- a/src/mapleall/maple_ir/include/global_tables.h +++ b/src/mapleall/maple_ir/include/global_tables.h @@ -631,6 +631,7 @@ class IntConstTable { IntConstTable &operator=(const IntConstTable &p) = delete; ~IntConstTable(); + MIRIntConst *GetOrCreateIntConst(const IntVal &val, MIRType &type); MIRIntConst *GetOrCreateIntConst(uint64 val, MIRType &type); static std::unique_ptr Create() { diff --git a/src/mapleall/maple_ir/src/global_tables.cpp b/src/mapleall/maple_ir/src/global_tables.cpp index f65057327f..a883692f45 100644 --- a/src/mapleall/maple_ir/src/global_tables.cpp +++ b/src/mapleall/maple_ir/src/global_tables.cpp @@ -296,6 +296,13 @@ void FPConstTable::PostInit() { minusZeroDoubleConst = new MIRDoubleConst(-0.0, typeDouble); } +MIRIntConst *IntConstTable::GetOrCreateIntConst(const IntVal &val, MIRType &type) { + if (ThreadEnv::IsMeParallel()) { + return DoGetOrCreateIntConstTreadSafe(val.GetExtValue(), type); + } + return DoGetOrCreateIntConst(val.GetExtValue(), type); +} + MIRIntConst *IntConstTable::GetOrCreateIntConst(uint64 val, MIRType &type) { if (ThreadEnv::IsMeParallel()) { return DoGetOrCreateIntConstTreadSafe(val, type); diff --git a/src/mapleall/maple_util/include/mpl_int_val.h b/src/mapleall/maple_util/include/mpl_int_val.h index da76b5db97..965048d349 100644 --- a/src/mapleall/maple_util/include/mpl_int_val.h +++ b/src/mapleall/maple_util/include/mpl_int_val.h @@ -312,6 +312,11 @@ class IntVal { return ret; } + IntVal LShr(uint64 shift) const { + ASSERT(shift <= width, "invalid shift value"); + return IntVal(value >> shift, width, sign); + } + // arithmetic right-shift operators (MSB is sign extended) IntVal AShr(const IntVal &shift, PrimType pType) const { return AShr(shift.value, pType); @@ -485,6 +490,14 @@ inline IntVal operator%(uint64 v1, const IntVal& v2) { return IntVal(v1, v2.GetBitWidth(), v2.IsSigned()) % v2; } +inline IntVal operator&(const IntVal &v1, uint64 v2) { + return v1 & IntVal(v2, v1.GetBitWidth(), v1.IsSigned()); +} + +inline IntVal operator&(uint64 v1, const IntVal &v2) { + return v2 & v1; +} + } // namespace maple #endif // MAPLE_UTIL_INCLUDE_MPL_INT_VAL_H diff --git a/src/mapleall/mpl2mpl/src/simplify.cpp b/src/mapleall/mpl2mpl/src/simplify.cpp index c46105f2fc..d836d61226 100644 --- a/src/mapleall/mpl2mpl/src/simplify.cpp +++ b/src/mapleall/mpl2mpl/src/simplify.cpp @@ -20,7 +20,10 @@ #include "constantfold.h" #include "mpl_logging.h" +namespace maple { + namespace { + constexpr char kClassNameOfMath[] = "Ljava_2Flang_2FMath_3B"; constexpr char kFuncNamePrefixOfMathSqrt[] = "Ljava_2Flang_2FMath_3B_7Csqrt_7C_28D_29D"; constexpr char kFuncNamePrefixOfMathAbs[] = "Ljava_2Flang_2FMath_3B_7Cabs_7C"; @@ -32,14 +35,48 @@ constexpr char kFuncNameOfMemcpy[] = "memcpy"; constexpr char kFuncNameOfMemsetS[] = "memset_s"; constexpr char kFuncNameOfMemcpyS[] = "memcpy_s"; constexpr uint64_t kSecurecMemMaxLen = 0x7fffffffUL; -static constexpr maple::int32 kProbUnlikely = 1000; +static constexpr int32 kProbUnlikely = 1000; constexpr uint32_t kMemsetDstOpndIdx = 0; constexpr uint32_t kMemsetSDstSizeOpndIdx = 1; constexpr uint32_t kMemsetSSrcOpndIdx = 2; constexpr uint32_t kMemsetSSrcSizeOpndIdx = 3; + +// Truncate the constant field of 'union' if it's written as scalar type (e.g. int), +// but accessed as bit-field type with smaller size. +// +// Return the truncated constant or nullptr if the constant doesn't need to be truncated. +MIRConst *TruncateUnionConstant(const MIRStructType &unionType, MIRConst *fieldCst, const MIRType &unionFieldType) { + if (unionType.GetKind() != kTypeUnion) { + return nullptr; + } + + auto *bitFieldType = safe_cast(unionFieldType); + auto *intCst = safe_cast(fieldCst); + + if (!bitFieldType || !intCst) { + return nullptr; + } + + bool isBigEndian = MeOption::IsBigEndian() || Options::IsBigEndian(); + + IntVal val = intCst->GetValue(); + uint8 bitSize = bitFieldType->GetFieldSize(); + + if (bitSize >= val.GetBitWidth()) { + return nullptr; + } + + if (isBigEndian) { + val = val.LShr(val.GetBitWidth() - bitSize); + } else { + val = val & ((uint64(1) << bitSize) - 1); + } + + return GlobalTables::GetIntConstTable().GetOrCreateIntConst(val, fieldCst->GetType()); +} + } // namespace -namespace maple { // If size (in byte) is bigger than this threshold, we won't expand memop const uint32 SimplifyMemOp::thresholdMemsetExpand = 512; const uint32 SimplifyMemOp::thresholdMemcpyExpand = 512; @@ -579,18 +616,26 @@ MIRConst *Simplify::GetElementConstFromFieldId(FieldID fieldId, MIRConst *mirCon auto originAggType = static_cast(originAggConst->GetType()); bool hasReached = false; std::function traverseAgg = [&] (MIRConst *currConst) { - auto currAggConst = static_cast(currConst); - auto currAggType = static_cast(currAggConst->GetType()); - auto iter = 0; - for (iter = 0; iter < currAggType.GetFieldsSize() && !hasReached; ++iter) { - auto constIdx = currAggType.GetKind() == kTypeUnion ? 1 : iter + 1; + auto* currAggConst = safe_cast(currConst); + ASSERT_NOT_NULL(currAggConst); + auto* currAggType = safe_cast(currAggConst->GetType()); + ASSERT_NOT_NULL(currAggType); + for (size_t iter = 0; iter < currAggType->GetFieldsSize() && !hasReached; ++iter) { + size_t constIdx = currAggType->GetKind() == kTypeUnion ? 1 : iter + 1; auto *fieldConst = currAggConst->GetAggConstElement(constIdx); auto *fieldType = originAggType.GetFieldType(currFieldId); + if (currFieldId == fieldId) { - resultConst = fieldConst; + if (auto *truncCst = TruncateUnionConstant(*currAggType, fieldConst, *fieldType)) { + resultConst = truncCst; + } else { + resultConst = fieldConst; + } + hasReached = true; return; } + ++currFieldId; if (fieldType->GetKind() == kTypeUnion || fieldType->GetKind() == kTypeStruct) { traverseAgg(fieldConst); -- Gitee From 4da8f257542d33ea11e13bfe375cbcec62cdc5bb Mon Sep 17 00:00:00 2001 From: Roman Rusyaev Date: Tue, 12 Jul 2022 12:15:33 +0300 Subject: [PATCH 2/3] Do not apply a peephole rule for elimination of unsigned extension instruction if call instruction returns signed value --- src/mapleall/maple_be/src/cg/aarch64/aarch64_peep.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/mapleall/maple_be/src/cg/aarch64/aarch64_peep.cpp b/src/mapleall/maple_be/src/cg/aarch64/aarch64_peep.cpp index 03e5438296..66f4b72037 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_peep.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_peep.cpp @@ -2914,6 +2914,7 @@ void EliminateSpecifcUXTAArch64::Run(BB &bb, Insn &insn) { auto ®Opnd0 = static_cast(insn.GetOperand(kInsnFirstOpnd)); auto ®Opnd1 = static_cast(insn.GetOperand(kInsnSecondOpnd)); if (prevInsn->IsCall() && + prevInsn->GetIsCallReturnUnsigned() && regOpnd0.GetRegisterNumber() == regOpnd1.GetRegisterNumber() && (regOpnd1.GetRegisterNumber() == R0 || regOpnd1.GetRegisterNumber() == V0)) { uint32 retSize = prevInsn->GetRetSize(); -- Gitee From cfd25b8bb3bb953efeadcf62e091354eb8a894b3 Mon Sep 17 00:00:00 2001 From: Roman Rusyaev Date: Tue, 12 Jul 2022 14:01:56 +0300 Subject: [PATCH 3/3] Refactor code and fix linter warnings --- src/mapleall/maple_ir/src/global_tables.cpp | 5 +---- src/mapleall/mpl2mpl/src/simplify.cpp | 24 ++++++++------------- 2 files changed, 10 insertions(+), 19 deletions(-) diff --git a/src/mapleall/maple_ir/src/global_tables.cpp b/src/mapleall/maple_ir/src/global_tables.cpp index a883692f45..17530e1a01 100644 --- a/src/mapleall/maple_ir/src/global_tables.cpp +++ b/src/mapleall/maple_ir/src/global_tables.cpp @@ -297,10 +297,7 @@ void FPConstTable::PostInit() { } MIRIntConst *IntConstTable::GetOrCreateIntConst(const IntVal &val, MIRType &type) { - if (ThreadEnv::IsMeParallel()) { - return DoGetOrCreateIntConstTreadSafe(val.GetExtValue(), type); - } - return DoGetOrCreateIntConst(val.GetExtValue(), type); + return GetOrCreateIntConst(static_cast(val.GetExtValue()), type); } MIRIntConst *IntConstTable::GetOrCreateIntConst(uint64 val, MIRType &type) { diff --git a/src/mapleall/mpl2mpl/src/simplify.cpp b/src/mapleall/mpl2mpl/src/simplify.cpp index d836d61226..196da56276 100644 --- a/src/mapleall/mpl2mpl/src/simplify.cpp +++ b/src/mapleall/mpl2mpl/src/simplify.cpp @@ -43,18 +43,17 @@ constexpr uint32_t kMemsetSSrcSizeOpndIdx = 3; // Truncate the constant field of 'union' if it's written as scalar type (e.g. int), // but accessed as bit-field type with smaller size. -// -// Return the truncated constant or nullptr if the constant doesn't need to be truncated. +// Return the truncated constant or the original constant 'fieldCst' if the constant doesn't need to be truncated. MIRConst *TruncateUnionConstant(const MIRStructType &unionType, MIRConst *fieldCst, const MIRType &unionFieldType) { - if (unionType.GetKind() != kTypeUnion) { - return nullptr; + if (!fieldCst || unionType.GetKind() != kTypeUnion) { + return fieldCst; } auto *bitFieldType = safe_cast(unionFieldType); auto *intCst = safe_cast(fieldCst); if (!bitFieldType || !intCst) { - return nullptr; + return fieldCst; } bool isBigEndian = MeOption::IsBigEndian() || Options::IsBigEndian(); @@ -63,7 +62,7 @@ MIRConst *TruncateUnionConstant(const MIRStructType &unionType, MIRConst *fieldC uint8 bitSize = bitFieldType->GetFieldSize(); if (bitSize >= val.GetBitWidth()) { - return nullptr; + return fieldCst; } if (isBigEndian) { @@ -620,19 +619,15 @@ MIRConst *Simplify::GetElementConstFromFieldId(FieldID fieldId, MIRConst *mirCon ASSERT_NOT_NULL(currAggConst); auto* currAggType = safe_cast(currAggConst->GetType()); ASSERT_NOT_NULL(currAggType); - for (size_t iter = 0; iter < currAggType->GetFieldsSize() && !hasReached; ++iter) { - size_t constIdx = currAggType->GetKind() == kTypeUnion ? 1 : iter + 1; + for (unsigned iter = 0; iter < currAggType->GetFieldsSize() && !hasReached; ++iter) { + unsigned constIdx = currAggType->GetKind() == kTypeUnion ? 1 : iter + 1; auto *fieldConst = currAggConst->GetAggConstElement(constIdx); auto *fieldType = originAggType.GetFieldType(currFieldId); if (currFieldId == fieldId) { - if (auto *truncCst = TruncateUnionConstant(*currAggType, fieldConst, *fieldType)) { - resultConst = truncCst; - } else { - resultConst = fieldConst; - } - + resultConst = TruncateUnionConstant(*currAggType, fieldConst, *fieldType); hasReached = true; + return; } @@ -1642,7 +1637,6 @@ bool SimplifyMemOp::SimplifyMemset(StmtNode &stmt, BlockNode &block, bool isLowL stmt.Dump(0); } - StmtNode *memsetCallStmt = &stmt; if (memOpKind == MEM_OP_memset_s && !isLowLevel) { memsetCallStmt = PartiallyExpandMemsetS(stmt, block); -- Gitee