Moved knowledge on masking shift operands to simplifier.
Rationale:
It is better to have a single place that simplifies shift
factors outside the 32-bit or 64-bit distance range, so
that other phases (induction variable analysis, loop optimizations,
etc.) do not have to know about that.
Test: test-art-target, test-art-host
Change-Id: Idfd90259cca085426cc3055eccb90f3c0976036b
diff --git a/compiler/optimizing/instruction_simplifier.cc b/compiler/optimizing/instruction_simplifier.cc
index 2dcc12e..2cedde9 100644
--- a/compiler/optimizing/instruction_simplifier.cc
+++ b/compiler/optimizing/instruction_simplifier.cc
@@ -257,7 +257,8 @@
if (shift_amount->IsConstant()) {
int64_t cst = Int64FromConstant(shift_amount->AsConstant());
- if ((cst & implicit_mask) == 0) {
+ int64_t masked_cst = cst & implicit_mask;
+ if (masked_cst == 0) {
// Replace code looking like
// SHL dst, value, 0
// with
@@ -266,6 +267,17 @@
instruction->GetBlock()->RemoveInstruction(instruction);
RecordSimplification();
return;
+ } else if (masked_cst != cst) {
+ // Replace code looking like
+ // SHL dst, value, cst
+ // where cst exceeds maximum distance with the equivalent
+ // SHL dst, value, cst & implicit_mask
+ // (as defined by shift semantics). This ensures other
+ // optimizations do not need to special case for such situations.
+ DCHECK_EQ(shift_amount->GetType(), Primitive::kPrimInt);
+ instruction->ReplaceInput(GetGraph()->GetIntConstant(masked_cst), /* index */ 1);
+ RecordSimplification();
+ return;
}
}
diff --git a/compiler/optimizing/loop_optimization.cc b/compiler/optimizing/loop_optimization.cc
index bbc55dd..881802d 100644
--- a/compiler/optimizing/loop_optimization.cc
+++ b/compiler/optimizing/loop_optimization.cc
@@ -71,7 +71,7 @@
// extension when represented in the *width* of the given narrower data type
// (the fact that char normally zero extends does not matter here).
int64_t value = 0;
- if (IsInt64AndGet(instruction, &value)) {
+ if (IsInt64AndGet(instruction, /*out*/ &value)) {
switch (type) {
case Primitive::kPrimByte:
if (std::numeric_limits<int8_t>::min() <= value &&
@@ -119,7 +119,7 @@
// extension when represented in the *width* of the given narrower data type
// (the fact that byte/short normally sign extend does not matter here).
int64_t value = 0;
- if (IsInt64AndGet(instruction, &value)) {
+ if (IsInt64AndGet(instruction, /*out*/ &value)) {
switch (type) {
case Primitive::kPrimByte:
if (std::numeric_limits<uint8_t>::min() <= value &&
@@ -833,19 +833,14 @@
// TODO: accept symbolic, albeit loop invariant shift factors.
HInstruction* opa = instruction->InputAt(0);
HInstruction* opb = instruction->InputAt(1);
- int64_t value = 0;
- if (VectorizeUse(node, opa, generate_code, type, restrictions) && IsInt64AndGet(opb, &value)) {
- // Make sure shift distance only looks at lower bits, as defined for sequential shifts.
- int64_t mask = (instruction->GetType() == Primitive::kPrimLong)
- ? kMaxLongShiftDistance
- : kMaxIntShiftDistance;
- int64_t distance = value & mask;
+ int64_t distance = 0;
+ if (VectorizeUse(node, opa, generate_code, type, restrictions) &&
+ IsInt64AndGet(opb, /*out*/ &distance)) {
// Restrict shift distance to packed data type width.
int64_t max_distance = Primitive::ComponentSize(type) * 8;
if (0 <= distance && distance < max_distance) {
if (generate_code) {
- HInstruction* s = graph_->GetIntConstant(distance);
- GenerateVecOp(instruction, vector_map_->Get(opa), s, type);
+ GenerateVecOp(instruction, vector_map_->Get(opa), opb, type);
}
return true;
}
@@ -1177,14 +1172,14 @@
int64_t value = 0;
if ((instruction->IsShr() ||
instruction->IsUShr()) &&
- IsInt64AndGet(instruction->InputAt(1), &value) && value == 1) {
+ IsInt64AndGet(instruction->InputAt(1), /*out*/ &value) && value == 1) {
//
// TODO: make following code less sensitive to associativity and commutativity differences.
//
HInstruction* x = instruction->InputAt(0);
// Test for an optional rounding part (x + 1) >> 1.
bool is_rounded = false;
- if (x->IsAdd() && IsInt64AndGet(x->InputAt(1), &value) && value == 1) {
+ if (x->IsAdd() && IsInt64AndGet(x->InputAt(1), /*out*/ &value) && value == 1) {
x = x->InputAt(0);
is_rounded = true;
}
diff --git a/test/551-checker-shifter-operand/src/Main.java b/test/551-checker-shifter-operand/src/Main.java
index e967398..bf09a6a 100644
--- a/test/551-checker-shifter-operand/src/Main.java
+++ b/test/551-checker-shifter-operand/src/Main.java
@@ -642,6 +642,123 @@
// Each test line below should see one merge.
+ //
+ /// CHECK-START: void Main.$opt$validateShiftInt(int, int) instruction_simplifier$after_inlining (before)
+ /// CHECK: Shl
+ /// CHECK: Shl
+ /// CHECK: Shl
+ /// CHECK: Shl
+ /// CHECK: Shl
+ /// CHECK: Shl
+ /// CHECK: Shl
+ /// CHECK: Shl
+ /// CHECK: Shl
+ /// CHECK: Shl
+ /// CHECK: Shl
+ /// CHECK: Shl
+ /// CHECK-NOT: Shl
+ /// CHECK: Shr
+ /// CHECK: Shr
+ /// CHECK: Shr
+ /// CHECK: Shr
+ /// CHECK: Shr
+ /// CHECK: Shr
+ /// CHECK: Shr
+ /// CHECK: Shr
+ /// CHECK: Shr
+ /// CHECK: Shr
+ /// CHECK: Shr
+ /// CHECK: Shr
+ /// CHECK-NOT: Shl
+ /// CHECK: UShr
+ /// CHECK: UShr
+ /// CHECK: UShr
+ /// CHECK: UShr
+ /// CHECK: UShr
+ /// CHECK: UShr
+ /// CHECK: UShr
+ /// CHECK: UShr
+ /// CHECK: UShr
+ /// CHECK: UShr
+ /// CHECK: UShr
+ /// CHECK: UShr
+ /// CHECK-NOT: UShr
+ //
+ // Note: simplification after inlining removes `b << 32`, `b >> 32` and `b >>> 32`.
+ //
+ /// CHECK-START: void Main.$opt$validateShiftInt(int, int) instruction_simplifier$after_inlining (after)
+ /// CHECK: Shl
+ /// CHECK: Shl
+ /// CHECK: Shl
+ /// CHECK: Shl
+ /// CHECK: Shl
+ /// CHECK: Shl
+ /// CHECK: Shl
+ /// CHECK: Shl
+ /// CHECK: Shl
+ /// CHECK: Shl
+ /// CHECK: Shl
+ /// CHECK-NOT: Shl
+ /// CHECK: Shr
+ /// CHECK: Shr
+ /// CHECK: Shr
+ /// CHECK: Shr
+ /// CHECK: Shr
+ /// CHECK: Shr
+ /// CHECK: Shr
+ /// CHECK: Shr
+ /// CHECK: Shr
+ /// CHECK: Shr
+ /// CHECK: Shr
+ /// CHECK-NOT: Shl
+ /// CHECK: UShr
+ /// CHECK: UShr
+ /// CHECK: UShr
+ /// CHECK: UShr
+ /// CHECK: UShr
+ /// CHECK: UShr
+ /// CHECK: UShr
+ /// CHECK: UShr
+ /// CHECK: UShr
+ /// CHECK: UShr
+ /// CHECK: UShr
+ /// CHECK-NOT: UShr
+ //
+ // Note: simplification followed by GVN exposes the common subexpressions between shifts with larger distance
+ // `b << 62`, `b << 63` etc. and the equivalent smaller distances.
+ //
+ /// CHECK-START: void Main.$opt$validateShiftInt(int, int) GVN (after)
+ /// CHECK: Shl
+ /// CHECK: Shl
+ /// CHECK: Shl
+ /// CHECK: Shl
+ /// CHECK: Shl
+ /// CHECK: Shl
+ /// CHECK: Shl
+ /// CHECK: Shl
+ /// CHECK: Shl
+ /// CHECK-NOT: Shl
+ /// CHECK: Shr
+ /// CHECK: Shr
+ /// CHECK: Shr
+ /// CHECK: Shr
+ /// CHECK: Shr
+ /// CHECK: Shr
+ /// CHECK: Shr
+ /// CHECK: Shr
+ /// CHECK: Shr
+ /// CHECK-NOT: Shl
+ /// CHECK: UShr
+ /// CHECK: UShr
+ /// CHECK: UShr
+ /// CHECK: UShr
+ /// CHECK: UShr
+ /// CHECK: UShr
+ /// CHECK: UShr
+ /// CHECK: UShr
+ /// CHECK: UShr
+ /// CHECK-NOT: UShr
+ //
/// CHECK-START-ARM: void Main.$opt$validateShiftInt(int, int) instruction_simplifier_arm (after)
/// CHECK: DataProcWithShifterOp
/// CHECK: DataProcWithShifterOp
@@ -670,14 +787,7 @@
/// CHECK: DataProcWithShifterOp
/// CHECK: DataProcWithShifterOp
/// CHECK: DataProcWithShifterOp
- /// CHECK: DataProcWithShifterOp
- /// CHECK: DataProcWithShifterOp
- /// CHECK: DataProcWithShifterOp
- /// CHECK: DataProcWithShifterOp
- /// CHECK: DataProcWithShifterOp
- /// CHECK: DataProcWithShifterOp
/// CHECK-NOT: DataProcWithShifterOp
- // Note: `b << 32`, `b >> 32` and `b >>> 32` are optimized away by generic simplifier.
/// CHECK-START-ARM: void Main.$opt$validateShiftInt(int, int) instruction_simplifier_arm (after)
/// CHECK-NOT: Shl
@@ -712,14 +822,7 @@
/// CHECK: DataProcWithShifterOp
/// CHECK: DataProcWithShifterOp
/// CHECK: DataProcWithShifterOp
- /// CHECK: DataProcWithShifterOp
- /// CHECK: DataProcWithShifterOp
- /// CHECK: DataProcWithShifterOp
- /// CHECK: DataProcWithShifterOp
- /// CHECK: DataProcWithShifterOp
- /// CHECK: DataProcWithShifterOp
/// CHECK-NOT: DataProcWithShifterOp
- // Note: `b << 32`, `b >> 32` and `b >>> 32` are optimized away by generic simplifier.
/// CHECK-START-ARM64: void Main.$opt$validateShiftInt(int, int) instruction_simplifier_arm64 (after)
/// CHECK-NOT: Shl
diff --git a/test/640-checker-int-simd/src/Main.java b/test/640-checker-int-simd/src/Main.java
index ba1e142..97048eb 100644
--- a/test/640-checker-int-simd/src/Main.java
+++ b/test/640-checker-int-simd/src/Main.java
@@ -76,6 +76,7 @@
/// CHECK-DAG: ArraySet loop:<<Loop>> outer_loop:none
//
/// CHECK-START: void Main.div(int) loop_optimization (after)
+ /// CHECK-NOT: VecDiv
//
// Not supported on any architecture.
//
@@ -159,14 +160,81 @@
// Shift sanity.
//
+ // Expose constants to optimizing compiler, but not to front-end.
+ public static int $opt$inline$IntConstant32() { return 32; }
+ public static int $opt$inline$IntConstant33() { return 33; }
+ public static int $opt$inline$IntConstantMinus254() { return -254; }
+
+ /// CHECK-START: void Main.shr32() instruction_simplifier$after_inlining (before)
+ /// CHECK-DAG: <<Dist:i\d+>> IntConstant 32 loop:none
+ /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none
+ /// CHECK-DAG: <<Get:i\d+>> ArrayGet loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<UShr:i\d+>> UShr [<<Get>>,<<Dist>>] loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: ArraySet [{{l\d+}},{{i\d+}},<<UShr>>] loop:<<Loop>> outer_loop:none
+ //
+ /// CHECK-START: void Main.shr32() instruction_simplifier$after_inlining (after)
+ /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none
+ /// CHECK-DAG: <<Get:i\d+>> ArrayGet loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: ArraySet [{{l\d+}},{{i\d+}},<<Get>>] loop:<<Loop>> outer_loop:none
+ //
+ /// CHECK-START-ARM64: void Main.shr32() loop_optimization (after)
+ /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none
+ /// CHECK-DAG: <<Get:d\d+>> VecLoad loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: VecStore [{{l\d+}},<<Phi>>,<<Get>>] loop:<<Loop>> outer_loop:none
static void shr32() {
+ // TODO: remove a[i] = a[i] altogether?
for (int i = 0; i < 128; i++)
- a[i] >>>= 32; // 0, since & 31
+ a[i] >>>= $opt$inline$IntConstant32(); // 0, since & 31
}
+ /// CHECK-START: void Main.shr33() instruction_simplifier$after_inlining (before)
+ /// CHECK-DAG: <<Dist:i\d+>> IntConstant 33 loop:none
+ /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none
+ /// CHECK-DAG: <<Get:i\d+>> ArrayGet loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<UShr:i\d+>> UShr [<<Get>>,<<Dist>>] loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: ArraySet [{{l\d+}},{{i\d+}},<<UShr>>] loop:<<Loop>> outer_loop:none
+ //
+ /// CHECK-START: void Main.shr33() instruction_simplifier$after_inlining (after)
+ /// CHECK-DAG: <<Dist:i\d+>> IntConstant 1 loop:none
+ /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none
+ /// CHECK-DAG: <<Get:i\d+>> ArrayGet loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<UShr:i\d+>> UShr [<<Get>>,<<Dist>>] loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: ArraySet [{{l\d+}},{{i\d+}},<<UShr>>] loop:<<Loop>> outer_loop:none
+ //
+ /// CHECK-START-ARM64: void Main.shr33() loop_optimization (after)
+ /// CHECK-DAG: <<Dist:i\d+>> IntConstant 1 loop:none
+ /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none
+ /// CHECK-DAG: <<Get:d\d+>> VecLoad loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<UShr:d\d+>> VecUShr [<<Get>>,<<Dist>>] loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: VecStore [{{l\d+}},<<Phi>>,<<UShr>>] loop:<<Loop>> outer_loop:none
static void shr33() {
for (int i = 0; i < 128; i++)
- a[i] >>>= 33; // 1, since & 31
+ a[i] >>>= $opt$inline$IntConstant33(); // 1, since & 31
+ }
+
+ /// CHECK-START: void Main.shrMinus254() instruction_simplifier$after_inlining (before)
+ /// CHECK-DAG: <<Dist:i\d+>> IntConstant -254 loop:none
+ /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none
+ /// CHECK-DAG: <<Get:i\d+>> ArrayGet loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<UShr:i\d+>> UShr [<<Get>>,<<Dist>>] loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: ArraySet [{{l\d+}},{{i\d+}},<<UShr>>] loop:<<Loop>> outer_loop:none
+ //
+ /// CHECK-START: void Main.shrMinus254() instruction_simplifier$after_inlining (after)
+ /// CHECK-DAG: <<Dist:i\d+>> IntConstant 2 loop:none
+ /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none
+ /// CHECK-DAG: <<Get:i\d+>> ArrayGet loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<UShr:i\d+>> UShr [<<Get>>,<<Dist>>] loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: ArraySet [{{l\d+}},{{i\d+}},<<UShr>>] loop:<<Loop>> outer_loop:none
+ //
+ /// CHECK-START-ARM64: void Main.shrMinus254() loop_optimization (after)
+ /// CHECK-DAG: <<Dist:i\d+>> IntConstant 2 loop:none
+ /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none
+ /// CHECK-DAG: <<Get:d\d+>> VecLoad loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<UShr:d\d+>> VecUShr [<<Get>>,<<Dist>>] loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: VecStore [{{l\d+}},<<Phi>>,<<UShr>>] loop:<<Loop>> outer_loop:none
+ static void shrMinus254() {
+ for (int i = 0; i < 128; i++)
+ a[i] >>>= $opt$inline$IntConstantMinus254(); // 2, since & 31
}
//
@@ -240,9 +308,14 @@
for (int i = 0; i < 128; i++) {
expectEquals(0x1fffffff, a[i], "shr33");
}
+ shrMinus254();
+ for (int i = 0; i < 128; i++) {
+ expectEquals(0x07ffffff, a[i], "shrMinus254");
+ }
+ // Bit-wise not operator.
not();
for (int i = 0; i < 128; i++) {
- expectEquals(0xe0000000, a[i], "not");
+ expectEquals(0xf8000000, a[i], "not");
}
// Done.
System.out.println("passed");
diff --git a/test/640-checker-long-simd/src/Main.java b/test/640-checker-long-simd/src/Main.java
index 5641182..e42c716 100644
--- a/test/640-checker-long-simd/src/Main.java
+++ b/test/640-checker-long-simd/src/Main.java
@@ -74,6 +74,7 @@
/// CHECK-DAG: ArraySet loop:<<Loop>> outer_loop:none
//
/// CHECK-START: void Main.div(long) loop_optimization (after)
+ /// CHECK-NOT: VecDiv
//
// Not supported on any architecture.
//
@@ -157,14 +158,81 @@
// Shift sanity.
//
+ // Expose constants to optimizing compiler, but not to front-end.
+ public static int $opt$inline$IntConstant64() { return 64; }
+ public static int $opt$inline$IntConstant65() { return 65; }
+ public static int $opt$inline$IntConstantMinus254() { return -254; }
+
+ /// CHECK-START: void Main.shr64() instruction_simplifier$after_inlining (before)
+ /// CHECK-DAG: <<Dist:i\d+>> IntConstant 64 loop:none
+ /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none
+ /// CHECK-DAG: <<Get:j\d+>> ArrayGet loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<UShr:j\d+>> UShr [<<Get>>,<<Dist>>] loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: ArraySet [{{l\d+}},{{i\d+}},<<UShr>>] loop:<<Loop>> outer_loop:none
+ //
+ /// CHECK-START: void Main.shr64() instruction_simplifier$after_inlining (after)
+ /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none
+ /// CHECK-DAG: <<Get:j\d+>> ArrayGet loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: ArraySet [{{l\d+}},{{i\d+}},<<Get>>] loop:<<Loop>> outer_loop:none
+ //
+ /// CHECK-START-ARM64: void Main.shr64() loop_optimization (after)
+ /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none
+ /// CHECK-DAG: <<Get:d\d+>> VecLoad loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: VecStore [{{l\d+}},<<Phi>>,<<Get>>] loop:<<Loop>> outer_loop:none
static void shr64() {
+ // TODO: remove a[i] = a[i] altogether?
for (int i = 0; i < 128; i++)
- a[i] >>>= 64; // 0, since & 63
+ a[i] >>>= $opt$inline$IntConstant64(); // 0, since & 63
}
+ /// CHECK-START: void Main.shr65() instruction_simplifier$after_inlining (before)
+ /// CHECK-DAG: <<Dist:i\d+>> IntConstant 65 loop:none
+ /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none
+ /// CHECK-DAG: <<Get:j\d+>> ArrayGet loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<UShr:j\d+>> UShr [<<Get>>,<<Dist>>] loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: ArraySet [{{l\d+}},{{i\d+}},<<UShr>>] loop:<<Loop>> outer_loop:none
+ //
+ /// CHECK-START: void Main.shr65() instruction_simplifier$after_inlining (after)
+ /// CHECK-DAG: <<Dist:i\d+>> IntConstant 1 loop:none
+ /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none
+ /// CHECK-DAG: <<Get:j\d+>> ArrayGet loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<UShr:j\d+>> UShr [<<Get>>,<<Dist>>] loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: ArraySet [{{l\d+}},{{i\d+}},<<UShr>>] loop:<<Loop>> outer_loop:none
+ //
+ /// CHECK-START-ARM64: void Main.shr65() loop_optimization (after)
+ /// CHECK-DAG: <<Dist:i\d+>> IntConstant 1 loop:none
+ /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none
+ /// CHECK-DAG: <<Get:d\d+>> VecLoad loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<UShr:d\d+>> VecUShr [<<Get>>,<<Dist>>] loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: VecStore [{{l\d+}},<<Phi>>,<<UShr>>] loop:<<Loop>> outer_loop:none
static void shr65() {
for (int i = 0; i < 128; i++)
- a[i] >>>= 65; // 1, since & 63
+ a[i] >>>= $opt$inline$IntConstant65(); // 1, since & 63
+ }
+
+ /// CHECK-START: void Main.shrMinus254() instruction_simplifier$after_inlining (before)
+ /// CHECK-DAG: <<Dist:i\d+>> IntConstant -254 loop:none
+ /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none
+ /// CHECK-DAG: <<Get:j\d+>> ArrayGet loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<UShr:j\d+>> UShr [<<Get>>,<<Dist>>] loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: ArraySet [{{l\d+}},{{i\d+}},<<UShr>>] loop:<<Loop>> outer_loop:none
+ //
+ /// CHECK-START: void Main.shrMinus254() instruction_simplifier$after_inlining (after)
+ /// CHECK-DAG: <<Dist:i\d+>> IntConstant 2 loop:none
+ /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none
+ /// CHECK-DAG: <<Get:j\d+>> ArrayGet loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<UShr:j\d+>> UShr [<<Get>>,<<Dist>>] loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: ArraySet [{{l\d+}},{{i\d+}},<<UShr>>] loop:<<Loop>> outer_loop:none
+ //
+ /// CHECK-START-ARM64: void Main.shrMinus254() loop_optimization (after)
+ /// CHECK-DAG: <<Dist:i\d+>> IntConstant 2 loop:none
+ /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none
+ /// CHECK-DAG: <<Get:d\d+>> VecLoad loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<UShr:d\d+>> VecUShr [<<Get>>,<<Dist>>] loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: VecStore [{{l\d+}},<<Phi>>,<<UShr>>] loop:<<Loop>> outer_loop:none
+ static void shrMinus254() {
+ for (int i = 0; i < 128; i++)
+ a[i] >>>= $opt$inline$IntConstantMinus254(); // 2, since & 63
}
//
@@ -238,9 +306,14 @@
for (int i = 0; i < 128; i++) {
expectEquals(0x1fffffffffffffffL, a[i], "shr65");
}
+ shrMinus254();
+ for (int i = 0; i < 128; i++) {
+ expectEquals(0x07ffffffffffffffL, a[i], "shrMinus254");
+ }
+ // Bit-wise not operator.
not();
for (int i = 0; i < 128; i++) {
- expectEquals(0xe000000000000000L, a[i], "not");
+ expectEquals(0xf800000000000000L, a[i], "not");
}
// Done.
System.out.println("passed");