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 03e5438296d28d53738e01cc2dd093b31a476ef4..66f4b7203754a4cae9d2cef49cc2fa1661042664 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(); diff --git a/src/mapleall/maple_ir/include/global_tables.h b/src/mapleall/maple_ir/include/global_tables.h index 0eef3dddc6ebf9b799dcc8c39a92030b350860ba..2c4ba0c3631a3ef6982b82f3cf17968e74af7610 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 f65057327f34dd77aba9d39367c78176f270b2e9..17530e1a013b5f9d4ac33533102b880758a05329 100644 --- a/src/mapleall/maple_ir/src/global_tables.cpp +++ b/src/mapleall/maple_ir/src/global_tables.cpp @@ -296,6 +296,10 @@ void FPConstTable::PostInit() { minusZeroDoubleConst = new MIRDoubleConst(-0.0, typeDouble); } +MIRIntConst *IntConstTable::GetOrCreateIntConst(const IntVal &val, MIRType &type) { + return GetOrCreateIntConst(static_cast(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 da76b5db97a0e3d7e1aea11656281ab0fd633e3d..965048d34917c0d5c501bfd5996ea3268b8f8f95 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 c46105f2fc12f831ec6959795a3fe2041c777ac0..196da56276b89d6b983682b7a79f572f6bab3e29 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,47 @@ 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 the original constant 'fieldCst' if the constant doesn't need to be truncated. +MIRConst *TruncateUnionConstant(const MIRStructType &unionType, MIRConst *fieldCst, const MIRType &unionFieldType) { + if (!fieldCst || unionType.GetKind() != kTypeUnion) { + return fieldCst; + } + + auto *bitFieldType = safe_cast(unionFieldType); + auto *intCst = safe_cast(fieldCst); + + if (!bitFieldType || !intCst) { + return fieldCst; + } + + bool isBigEndian = MeOption::IsBigEndian() || Options::IsBigEndian(); + + IntVal val = intCst->GetValue(); + uint8 bitSize = bitFieldType->GetFieldSize(); + + if (bitSize >= val.GetBitWidth()) { + return fieldCst; + } + + 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 +615,22 @@ 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 (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) { - resultConst = fieldConst; + resultConst = TruncateUnionConstant(*currAggType, fieldConst, *fieldType); hasReached = true; + return; } + ++currFieldId; if (fieldType->GetKind() == kTypeUnion || fieldType->GetKind() == kTypeStruct) { traverseAgg(fieldConst); @@ -1597,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);