Fix the output type of HNegate.
TBR=sigmund@google.com Change-Id: If5875aac80f111bb95852ad4d9f568dadf4f9d65 Reviewed-on: https://dart-review.googlesource.com/51980 Reviewed-by: Stephen Adams <sra@google.com> Reviewed-by: Sigmund Cherem <sigmund@google.com> Commit-Queue: Stephen Adams <sra@google.com>
This commit is contained in:
committed by
commit-bot@chromium.org
parent
2f9f8088b5
commit
32df3387f2
@@ -248,8 +248,18 @@ class UnaryNegateSpecializer extends InvokeDynamicSpecializer {
|
||||
GlobalTypeInferenceResults results,
|
||||
CompilerOptions options,
|
||||
ClosedWorld closedWorld) {
|
||||
TypeMask operandType = instruction.inputs[1].instructionType;
|
||||
if (instruction.inputs[1].isNumberOrNull(closedWorld)) return operandType;
|
||||
HInstruction operand = instruction.inputs[1];
|
||||
if (operand.isNumberOrNull(closedWorld)) {
|
||||
// We have integer subclasses that represent ranges, so widen any int
|
||||
// subclass to full integer.
|
||||
if (operand.isIntegerOrNull(closedWorld)) {
|
||||
return closedWorld.commonMasks.intType;
|
||||
}
|
||||
if (operand.isDoubleOrNull(closedWorld)) {
|
||||
return closedWorld.commonMasks.doubleType;
|
||||
}
|
||||
return closedWorld.commonMasks.numType;
|
||||
}
|
||||
return super
|
||||
.computeTypeFromInputTypes(instruction, results, options, closedWorld);
|
||||
}
|
||||
@@ -263,7 +273,11 @@ class UnaryNegateSpecializer extends InvokeDynamicSpecializer {
|
||||
ClosedWorld closedWorld) {
|
||||
HInstruction input = instruction.inputs[1];
|
||||
if (input.isNumber(closedWorld)) {
|
||||
return new HNegate(input, instruction.selector, input.instructionType);
|
||||
return new HNegate(
|
||||
input,
|
||||
instruction.selector,
|
||||
computeTypeFromInputTypes(
|
||||
instruction, results, options, closedWorld));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
|
||||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
import 'package:async_helper/async_helper.dart';
|
||||
import '../compiler_helper.dart';
|
||||
|
||||
// A bug in UnaryNegateSpecializer left '-a' labelled as 'positive', allowing
|
||||
// misoptimization of '<<'.
|
||||
const String TEST1 = r"""
|
||||
foo(param) {
|
||||
var a = param ? 0xFFFFFFFF : 1;
|
||||
return 1 << -a;
|
||||
// present: '$shl'
|
||||
// absent: '_shlPositive'
|
||||
}
|
||||
""";
|
||||
|
||||
const String TEST2 = r"""
|
||||
foo(param) {
|
||||
var a = param ? 0xFFFFFFFF : 1;
|
||||
return 1 << a;
|
||||
// present: '_shlPositive'
|
||||
// absent: '$shl'
|
||||
}
|
||||
""";
|
||||
|
||||
main() {
|
||||
runTests({bool useKernel}) async {
|
||||
check(String test) async {
|
||||
await compile(test,
|
||||
entry: 'foo',
|
||||
useKernel: useKernel,
|
||||
check: checkerForAbsentPresent(test));
|
||||
}
|
||||
|
||||
await check(TEST1);
|
||||
await check(TEST2);
|
||||
}
|
||||
|
||||
asyncTest(() async {
|
||||
print('--test from ast---------------------------------------------------');
|
||||
await runTests(useKernel: false);
|
||||
print('--test from kernel------------------------------------------------');
|
||||
await runTests(useKernel: true);
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user