[vm/compiler] Consistently use PointerBase.data values as FFiIntPtr.

Also if converting an unboxed int with only non-negative values
that fit in 32 bits to a uint32, then keep the range from the value.

TEST=regress_306327173_il_test

Cq-Include-Trybots: luci.dart.try:vm-aot-linux-debug-simarm_x64-try,vm-aot-linux-release-x64-try,vm-aot-linux-debug-x64-try,vm-aot-linux-debug-x64c-try
Change-Id: Id9e7c2d5f477e560822a02574739c57d77b5a6d1
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/332202
Reviewed-by: Daco Harkes <dacoharkes@google.com>
Reviewed-by: Slava Egorov <vegorov@google.com>
Commit-Queue: Tess Strickland <sstrickl@google.com>
This commit is contained in:
Tess Strickland 2023-10-25 18:47:49 +00:00 committed by Commit Queue
parent 89886de2e8
commit 5c4fd50667
4 changed files with 40 additions and 49 deletions

View file

@ -17,32 +17,21 @@ import 'package:vm/testing/il_matchers.dart';
int identity(int address) => Pointer<Void>.fromAddress(address).address; int identity(int address) => Pointer<Void>.fromAddress(address).address;
void matchIL$identity(FlowGraph graph) { void matchIL$identity(FlowGraph graph) {
graph.dump(); final retval = is32BitConfiguration ? 'retval' : 'address';
if (is32BitConfiguration) { graph.match([
// The Dart int address is truncated before being returned. match.block('Graph'),
graph.match([ match.block('Function', [
match.block('Graph'), 'address' << match.Parameter(index: 0),
match.block('Function', [ if (is32BitConfiguration) ...[
'address' << match.Parameter(index: 0), // The Dart int address is truncated before being returned.
'int32' <<
match.IntConverter('address',
from: 'int64', to: 'int32', is_truncating: true),
'uint32' << 'uint32' <<
match.IntConverter('int32', match.IntConverter('address',
from: 'int32', to: 'uint32', is_truncating: true), from: 'int64', to: 'uint32', is_truncating: true),
'retval' << match.IntConverter('uint32', from: 'uint32', to: 'int64'), 'retval' << match.IntConverter('uint32', from: 'uint32', to: 'int64'),
match.Return('retval'), ],
]), match.Return(retval),
]); ]),
} else { ]);
graph.match([
match.block('Graph'),
match.block('Function', [
'address' << match.Parameter(index: 0),
match.Return('address'),
]),
]);
}
} }
void main(List<String> args) { void main(List<String> args) {

View file

@ -30,12 +30,7 @@ void matchIL$deref(FlowGraph graph) {
// and int64 on 64-bit arches. // and int64 on 64-bit arches.
if (is32BitConfiguration) ...[ if (is32BitConfiguration) ...[
// 'unboxed' needs to be converted to int64 before returning. // 'unboxed' needs to be converted to int64 before returning.
// 'address' << match.IntConverter('unboxed', from: 'uint32', to: 'int64'),
// Note: The first two conversions here should be fixed once all
// kUnboxedIntPtr uses are appropriately converted to kUnboxedFfiIntPtr.
'extra1' << match.IntConverter('unboxed', from: 'uint32', to: 'int32'),
'extra2' << match.IntConverter('extra1', from: 'int32', to: 'uint32'),
'address' << match.IntConverter('extra2', from: 'uint32', to: 'int64'),
], ],
match.Return(retvalName), match.Return(retvalName),
]), ]),

View file

@ -3168,8 +3168,14 @@ void IntConverterInstr::InferRange(RangeAnalysis* analysis, Range* range) {
*range = *value_range; *range = *value_range;
break; break;
case kUnboxedUint32: case kUnboxedUint32:
// TODO(vegorov): improve range information for unboxing to Uint32. if (value_range->IsWithin(0, kMaxUint32)) {
*range = Range::Full(to()); // All possible values fit in a uint32, either directly or just by
// truncating high bits that are guaranteed to be 0.
*range = *value_range;
} else {
// TODO(vegorov): improve range information for unboxing to Uint32.
*range = Range::Full(to());
}
break; break;
case kUnboxedInt32: case kUnboxedInt32:
switch (from()) { switch (from()) {

View file

@ -1370,8 +1370,8 @@ FlowGraph* FlowGraphBuilder::BuildGraphOfRecognizedMethod(
LocalVariable* pointer = MakeTemporary(); LocalVariable* pointer = MakeTemporary();
body += LoadLocal(pointer); body += LoadLocal(pointer);
body += LoadLocal(address); body += LoadLocal(address);
body += UnboxTruncate(kUnboxedIntPtr); body += UnboxTruncate(kUnboxedFfiIntPtr);
body += ConvertUnboxedToUntagged(kUnboxedIntPtr); body += ConvertUnboxedToUntagged(kUnboxedFfiIntPtr);
body += StoreNativeField(Slot::PointerBase_data(), body += StoreNativeField(Slot::PointerBase_data(),
InnerPointerAccess::kCannotBeInnerPointer, InnerPointerAccess::kCannotBeInnerPointer,
StoreFieldInstr::Kind::kInitializing); StoreFieldInstr::Kind::kInitializing);
@ -1453,8 +1453,8 @@ FlowGraph* FlowGraphBuilder::BuildGraphOfRecognizedMethod(
body += LoadLocal(MakeTemporary()); // Duplicate Pointer. body += LoadLocal(MakeTemporary()); // Duplicate Pointer.
body += LoadLocal(parsed_function_->RawParameterVariable(0)); // Address. body += LoadLocal(parsed_function_->RawParameterVariable(0)); // Address.
body += CheckNullOptimized(String::ZoneHandle(Z, function.name())); body += CheckNullOptimized(String::ZoneHandle(Z, function.name()));
body += UnboxTruncate(kUnboxedIntPtr); body += UnboxTruncate(kUnboxedFfiIntPtr);
body += ConvertUnboxedToUntagged(kUnboxedIntPtr); body += ConvertUnboxedToUntagged(kUnboxedFfiIntPtr);
body += StoreNativeField(Slot::PointerBase_data(), body += StoreNativeField(Slot::PointerBase_data(),
InnerPointerAccess::kCannotBeInnerPointer, InnerPointerAccess::kCannotBeInnerPointer,
StoreFieldInstr::Kind::kInitializing); StoreFieldInstr::Kind::kInitializing);
@ -1786,11 +1786,12 @@ Fragment FlowGraphBuilder::BuildTypedDataViewFactoryConstructor(
body += LoadLocal(typed_data); body += LoadLocal(typed_data);
body += LoadNativeField(Slot::PointerBase_data(), body += LoadNativeField(Slot::PointerBase_data(),
InnerPointerAccess::kMayBeInnerPointer); InnerPointerAccess::kMayBeInnerPointer);
body += ConvertUntaggedToUnboxed(kUnboxedIntPtr); body += ConvertUntaggedToUnboxed(kUnboxedFfiIntPtr);
body += LoadLocal(offset_in_bytes); body += LoadLocal(offset_in_bytes);
body += UnboxTruncate(kUnboxedIntPtr); body += UnboxTruncate(kUnboxedFfiIntPtr);
body += BinaryIntegerOp(Token::kADD, kUnboxedIntPtr, /*is_truncating=*/true); body +=
body += ConvertUnboxedToUntagged(kUnboxedIntPtr); BinaryIntegerOp(Token::kADD, kUnboxedFfiIntPtr, /*is_truncating=*/true);
body += ConvertUnboxedToUntagged(kUnboxedFfiIntPtr);
body += StoreNativeField(Slot::PointerBase_data(), body += StoreNativeField(Slot::PointerBase_data(),
InnerPointerAccess::kMayBeInnerPointer, InnerPointerAccess::kMayBeInnerPointer,
StoreFieldInstr::Kind::kInitializing); StoreFieldInstr::Kind::kInitializing);
@ -1851,27 +1852,27 @@ Fragment FlowGraphBuilder::BuildTypedDataMemMove(const Function& function,
call_memmove += LoadLocal(arg_to); call_memmove += LoadLocal(arg_to);
call_memmove += LoadNativeField(Slot::PointerBase_data(), call_memmove += LoadNativeField(Slot::PointerBase_data(),
InnerPointerAccess::kMayBeInnerPointer); InnerPointerAccess::kMayBeInnerPointer);
call_memmove += ConvertUntaggedToUnboxed(kUnboxedIntPtr); call_memmove += ConvertUntaggedToUnboxed(kUnboxedFfiIntPtr);
call_memmove += LoadLocal(arg_to_start); call_memmove += LoadLocal(arg_to_start);
call_memmove += IntConstant(element_size); call_memmove += IntConstant(element_size);
call_memmove += SmiBinaryOp(Token::kMUL, /*is_truncating=*/true); call_memmove += SmiBinaryOp(Token::kMUL, /*is_truncating=*/true);
call_memmove += UnboxTruncate(kUnboxedIntPtr); call_memmove += UnboxTruncate(kUnboxedFfiIntPtr);
call_memmove += call_memmove +=
BinaryIntegerOp(Token::kADD, kUnboxedIntPtr, /*is_truncating=*/true); BinaryIntegerOp(Token::kADD, kUnboxedFfiIntPtr, /*is_truncating=*/true);
call_memmove += LoadLocal(arg_from); call_memmove += LoadLocal(arg_from);
call_memmove += LoadNativeField(Slot::PointerBase_data(), call_memmove += LoadNativeField(Slot::PointerBase_data(),
InnerPointerAccess::kMayBeInnerPointer); InnerPointerAccess::kMayBeInnerPointer);
call_memmove += ConvertUntaggedToUnboxed(kUnboxedIntPtr); call_memmove += ConvertUntaggedToUnboxed(kUnboxedFfiIntPtr);
call_memmove += LoadLocal(arg_from_start); call_memmove += LoadLocal(arg_from_start);
call_memmove += IntConstant(element_size); call_memmove += IntConstant(element_size);
call_memmove += SmiBinaryOp(Token::kMUL, /*is_truncating=*/true); call_memmove += SmiBinaryOp(Token::kMUL, /*is_truncating=*/true);
call_memmove += UnboxTruncate(kUnboxedIntPtr); call_memmove += UnboxTruncate(kUnboxedFfiIntPtr);
call_memmove += call_memmove +=
BinaryIntegerOp(Token::kADD, kUnboxedIntPtr, /*is_truncating=*/true); BinaryIntegerOp(Token::kADD, kUnboxedFfiIntPtr, /*is_truncating=*/true);
call_memmove += LoadLocal(arg_count); call_memmove += LoadLocal(arg_count);
call_memmove += IntConstant(element_size); call_memmove += IntConstant(element_size);
call_memmove += SmiBinaryOp(Token::kMUL, /*is_truncating=*/true); call_memmove += SmiBinaryOp(Token::kMUL, /*is_truncating=*/true);
call_memmove += UnboxTruncate(kUnboxedIntPtr); call_memmove += UnboxTruncate(kUnboxedFfiIntPtr);
call_memmove += LoadThread(); call_memmove += LoadThread();
call_memmove += LoadUntagged( call_memmove += LoadUntagged(
compiler::target::Thread::OffsetFromThread(&kMemoryMoveRuntimeEntry)); compiler::target::Thread::OffsetFromThread(&kMemoryMoveRuntimeEntry));
@ -4515,8 +4516,8 @@ Fragment FlowGraphBuilder::FfiPointerFromAddress() {
LocalVariable* pointer = MakeTemporary(); LocalVariable* pointer = MakeTemporary();
code += LoadLocal(pointer); code += LoadLocal(pointer);
code += LoadLocal(address); code += LoadLocal(address);
code += UnboxTruncate(kUnboxedIntPtr); code += UnboxTruncate(kUnboxedFfiIntPtr);
code += ConvertUnboxedToUntagged(kUnboxedIntPtr); code += ConvertUnboxedToUntagged(kUnboxedFfiIntPtr);
code += StoreNativeField(Slot::PointerBase_data(), code += StoreNativeField(Slot::PointerBase_data(),
InnerPointerAccess::kCannotBeInnerPointer, InnerPointerAccess::kCannotBeInnerPointer,
StoreFieldInstr::Kind::kInitializing); StoreFieldInstr::Kind::kInitializing);