Merge "Add regression tests for 32-bit x86 struct layout bug fixes."
diff --git a/tests/java_api/RsTest/src/com/android/rs/test/RSTestCore.java b/tests/java_api/RsTest/src/com/android/rs/test/RSTestCore.java
index 0583cb7..ac8dad5 100644
--- a/tests/java_api/RsTest/src/com/android/rs/test/RSTestCore.java
+++ b/tests/java_api/RsTest/src/com/android/rs/test/RSTestCore.java
@@ -106,7 +106,10 @@
unitTests.add(new UT_reduce(this, mCtx));
unitTests.add(new UT_reduce_backward(this, mCtx));
unitTests.add(new UT_small_struct(this, mCtx));
+ unitTests.add(new UT_small_struct_2(this, mCtx));
unitTests.add(new UT_struct_field(this, mCtx));
+ unitTests.add(new UT_struct_field_simple(this, mCtx));
+ unitTests.add(new UT_bitfield(this, mCtx));
/*
unitTests.add(new UnitTest(null, "<Pass>", 1));
diff --git a/tests/java_api/RsTest/src/com/android/rs/test/UT_bitfield.java b/tests/java_api/RsTest/src/com/android/rs/test/UT_bitfield.java
new file mode 100644
index 0000000..4ba4b69
--- /dev/null
+++ b/tests/java_api/RsTest/src/com/android/rs/test/UT_bitfield.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.rs.test;
+
+import android.content.Context;
+import android.renderscript.RenderScript;
+
+public class UT_bitfield extends UnitTest {
+
+ protected UT_bitfield(RSTestCore rstc, Context ctx) {
+ super(rstc, "Bitfield", ctx);
+ }
+
+ public void run() {
+ RenderScript pRS = RenderScript.create(mCtx);
+ ScriptC_bitfield s = new ScriptC_bitfield(pRS);
+ pRS.setMessageHandler(mRsMessage);
+
+ final long L = 0x76543210fedcba98L;
+ final int I = 0x12345678;
+
+ s.invoke_choose(1);
+ s.invoke_setUnion(L, I);
+ s.invoke_testUnion(L, I);
+
+ pRS.finish();
+ waitForMessage();
+ pRS.destroy();
+ }
+}
diff --git a/tests/java_api/RsTest/src/com/android/rs/test/UT_small_struct.java b/tests/java_api/RsTest/src/com/android/rs/test/UT_small_struct.java
index 4f23b5d..ca96b61 100644
--- a/tests/java_api/RsTest/src/com/android/rs/test/UT_small_struct.java
+++ b/tests/java_api/RsTest/src/com/android/rs/test/UT_small_struct.java
@@ -21,6 +21,8 @@
import android.renderscript.RenderScript;
import android.renderscript.Type;
+// Same as UT_small_struct_2.java except for names of classes and of test.
+
public class UT_small_struct extends UnitTest {
private Allocation A;
private Allocation B;
diff --git a/tests/java_api/RsTest/src/com/android/rs/test/UT_small_struct_2.java b/tests/java_api/RsTest/src/com/android/rs/test/UT_small_struct_2.java
new file mode 100644
index 0000000..7f03b44
--- /dev/null
+++ b/tests/java_api/RsTest/src/com/android/rs/test/UT_small_struct_2.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.rs.test;
+
+import android.content.Context;
+import android.renderscript.Allocation;
+import android.renderscript.RenderScript;
+import android.renderscript.Type;
+
+// Same as UT_small_struct.java except for names of classes and of test.
+
+public class UT_small_struct_2 extends UnitTest {
+ private Allocation A;
+ private Allocation B;
+ private static final int dimX = 3;
+ private static final int dimY = 2;
+
+ protected UT_small_struct_2(RSTestCore rstc, Context ctx) {
+ super(rstc, "Small Structs 2", ctx);
+ }
+
+ private void initializeGlobals(RenderScript RS, ScriptC_small_struct_2 s) {
+ s.set_gDimX(dimX);
+ s.set_gDimY(dimY);
+
+ Type.Builder builderA = new Type.Builder(RS, ScriptField_small_struct_2.createElement(RS));
+ builderA.setX(dimX);
+ builderA.setY(dimY);
+
+ A = Allocation.createTyped(RS, builderA.create());
+ s.set_A(A);
+
+ Type.Builder builderB = new Type.Builder(RS, ScriptField_struct_of_struct_2.createElement(RS));
+ builderB.setX(dimX);
+ builderB.setY(dimY);
+
+ B = Allocation.createTyped(RS, builderB.create());
+ s.set_B(B);
+ return;
+ }
+
+ public void run() {
+ RenderScript pRS = RenderScript.create(mCtx);
+ ScriptC_small_struct_2 s = new ScriptC_small_struct_2(pRS);
+ pRS.setMessageHandler(mRsMessage);
+
+ initializeGlobals(pRS, s);
+ s.forEach_setStruct(A);
+ s.forEach_setArrayOfStruct(B);
+ s.invoke_test();
+
+ pRS.finish();
+ waitForMessage();
+ pRS.destroy();
+ }
+}
diff --git a/tests/java_api/RsTest/src/com/android/rs/test/UT_struct_field_simple.java b/tests/java_api/RsTest/src/com/android/rs/test/UT_struct_field_simple.java
new file mode 100644
index 0000000..748c2a3
--- /dev/null
+++ b/tests/java_api/RsTest/src/com/android/rs/test/UT_struct_field_simple.java
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.rs.test;
+
+import android.content.Context;
+import android.renderscript.RenderScript;
+
+public class UT_struct_field_simple extends UnitTest {
+
+ protected UT_struct_field_simple(RSTestCore rstc, Context ctx) {
+ super(rstc, "Structure Fields", ctx);
+ }
+
+ public void run() {
+ RenderScript pRS = RenderScript.create(mCtx);
+ ScriptC_struct_field_simple s = new ScriptC_struct_field_simple(pRS);
+ pRS.setMessageHandler(mRsMessage);
+
+ ScriptField_Simple.Item simple = new ScriptField_Simple.Item();
+ final int I = 0x12345678;
+ final long L = 0x76543210fedcba98L;
+ simple.I = I;
+ simple.L = L;
+ s.set_simple(simple);
+
+ s.invoke_checkSimple(I, L);
+
+ pRS.finish();
+ waitForMessage();
+ pRS.destroy();
+ }
+}
+
+// struct Simple {
+// int I;
+// long L;
+// };
+//
+// Consistently padded, we expect:
+// I = 0x12345678
+// L.lo = 0xfedcba98
+// L.hi = 0x76543210
+//
+// And indeed on N9 --abi armeabi-v7a (i.e., ARM-32) we see:
+//
+// 09-23 21:55:51.026 5990 6005 D RenderScript: argI 305419896 0x12345678
+// 09-23 21:55:51.026 5990 6005 D RenderScript: simple.I 305419896 0x12345678
+// 09-23 21:55:51.026 5990 6005 D RenderScript: argL.lo 4275878552 0xfedcba98
+// 09-23 21:55:51.026 5990 6005 D RenderScript: simple.L.lo 4275878552 0xfedcba98
+// 09-23 21:55:51.026 5990 6005 D RenderScript: argL.hi 1985229328 0x76543210
+// 09-23 21:55:51.026 5990 6005 D RenderScript: simple.L.hi 1985229328 0x76543210
+// 09-23 21:55:51.026 5990 6005 D RenderScript: struct_field_simple PASSED 0 0x0
+//
+// Inconsistently padded (Java pads, x86-32 script does not), we expect:
+// I = 0x12345678 // fine
+// L.lo = 0 // oops, script read the padding
+// L.hi = 0xfedcba98 // oops, script read L.lo
+//
+// And indeed on fugu (i.e., x86-32) before the fix for http://b/29154200 and http://b/28070272
+// we see:
+//
+// 09-23 21:39:19.775 4090 4107 D RenderScript: argI 305419896 0x12345678
+// 09-23 21:39:19.775 4090 4107 D RenderScript: simple.I 305419896 0x12345678
+// 09-23 21:39:19.775 4090 4107 D RenderScript: argL.lo 4275878552 0xfedcba98
+// 09-23 21:39:19.775 4090 4107 D RenderScript: simple.L.lo 0 0x0
+// 09-23 21:39:19.775 4090 4107 D RenderScript: argL.hi 1985229328 0x76543210
+// 09-23 21:39:19.775 4090 4107 D RenderScript: simple.L.hi 4275878552 0xfedcba98
+// 09-23 21:39:19.775 4090 4107 D RenderScript: simple.L == argL FAILED 0 0x0
+// 09-23 21:39:19.775 4090 4107 D RenderScript: struct_field_simple FAILED 0 0x0
diff --git a/tests/java_api/RsTest/src/com/android/rs/test/bitfield.rs b/tests/java_api/RsTest/src/com/android/rs/test/bitfield.rs
new file mode 100644
index 0000000..bce32f7
--- /dev/null
+++ b/tests/java_api/RsTest/src/com/android/rs/test/bitfield.rs
@@ -0,0 +1,87 @@
+#include "shared.rsh"
+
+// There is a C99 rule (under "Structure and union members") that
+// reads "One special guarantee is made in order to simplify the use
+// of unions: if a union contains several structures that share a
+// common initial sequence, and if the union object currently contains
+// one of these structures, it is permitted to inspect the common
+// initial part of any of them anywhere that a declaration of the
+// completed type of the union is visible. Two structures share a
+// common initial sequence if corresponding members have compatible
+// types (and, for bit-fields, the same widths) for a sequence of one
+// or more initial members."
+//
+// We want to ensure that the common initial sequences of exported
+// and non-exported types have the same layout.
+
+// An exported type (because we declare a global variable of this type)
+struct NoBitfield {
+ int I;
+ // expect 4 bytes of padding here
+ long L;
+ float F;
+ // expect 4 bytes of padding here
+};
+
+struct NoBitfield junk; // just to make this an exported type
+
+// A non-exported type that shares a common initial sequence with NoBitfield
+struct Bitfield {
+ int I;
+ // expect 4 bytes of padding here
+ long L;
+ uint U:3;
+};
+
+union CommonInitialSequence {
+ struct NoBitfield nbf;
+ struct Bitfield bf;
+};
+
+static union CommonInitialSequence U, V;
+
+static struct NoBitfield *nbf;
+static struct Bitfield * bf;
+
+// Note: Sets through the exported type (NoBitfield)
+void setUnion(long argL, int argI) {
+ nbf->L = argL;
+ nbf->I = argI;
+}
+
+// Note: Tests through the non-exported type (Bitfield)
+void testUnion(long argL, int argI) {
+ bool failed = false;
+
+ rsDebug("argI ", argI);
+ rsDebug("bf->I ", bf->I);
+ rsDebug("argL.lo ", (unsigned)argL & ~0U);
+ rsDebug("bf->L.lo", (unsigned)bf->L & ~0U);
+ rsDebug("argL.hi ", (unsigned)((ulong)argL >> 32));
+ rsDebug("bf->L.hi", (unsigned)((ulong)bf->L >> 32));
+
+ _RS_ASSERT(bf->I == argI);
+ _RS_ASSERT(bf->L == argL);
+
+ if (failed) {
+ rsDebug("bitfield FAILED", 0);
+ rsSendToClientBlocking(RS_MSG_TEST_FAILED);
+ }
+ else {
+ rsDebug("bitfield PASSED", 0);
+ rsSendToClientBlocking(RS_MSG_TEST_PASSED);
+ }
+}
+
+// Note: Prevent compiler from optimizing setUnion()/testUnion()
+// to convert indirect accesses through nbf/bf into direct
+// accesses through U or V.
+void choose(int i) {
+ if (i) {
+ nbf = &U.nbf;
+ bf = &U. bf;
+ } else {
+ nbf = &V.nbf;
+ bf = &V. bf;
+ }
+}
diff --git a/tests/java_api/RsTest/src/com/android/rs/test/small_struct.rs b/tests/java_api/RsTest/src/com/android/rs/test/small_struct.rs
index 9aa9677..4c1f437 100644
--- a/tests/java_api/RsTest/src/com/android/rs/test/small_struct.rs
+++ b/tests/java_api/RsTest/src/com/android/rs/test/small_struct.rs
@@ -1,3 +1,5 @@
+// Same as small_struct_2.rs except for location of padding in struct small_struct[_2].
+
#include "shared.rsh"
int gDimX;
@@ -11,6 +13,7 @@
typedef struct small_struct {
int i;
+ // expect 4 bytes of padding here
long l;
} small_struct;
diff --git a/tests/java_api/RsTest/src/com/android/rs/test/small_struct_2.rs b/tests/java_api/RsTest/src/com/android/rs/test/small_struct_2.rs
new file mode 100644
index 0000000..f56f999
--- /dev/null
+++ b/tests/java_api/RsTest/src/com/android/rs/test/small_struct_2.rs
@@ -0,0 +1,70 @@
+// Same as small_struct.rs except for location of padding in struct small_struct[_2].
+
+#include "shared.rsh"
+
+int gDimX;
+int gDimY;
+
+rs_allocation A;
+rs_allocation B;
+
+static int gIntStart = 0x7;
+static long gLongStart = 0x12345678abcdef12;
+
+typedef struct small_struct_2 {
+ long l;
+ int i;
+ // expect 4 bytes of padding here
+} small_struct_2;
+
+#define ARRAY_LEN 3
+
+typedef struct struct_of_struct_2 {
+ small_struct_2 arr[ARRAY_LEN];
+} struct_of_struct_2;
+
+void test() {
+ bool failed = false;
+ for (int x = 0; x < gDimX; x ++) {
+ for (int y = 0; y < gDimY; y ++) {
+ small_struct_2 *v = (small_struct_2 *) rsGetElementAt(A, x, y);
+ _RS_ASSERT_EQU(v->i, gIntStart + y * gDimX + x);
+ _RS_ASSERT_EQU(v->l, gLongStart + y * gDimX + x);
+ }
+ }
+
+ for (int x = 0; x < gDimX; x ++) {
+ for (int y = 0; y < gDimY; y ++) {
+ struct_of_struct_2 *v = (struct_of_struct_2 *) rsGetElementAt(B, x, y);
+ for (int idx = 0; idx < ARRAY_LEN; idx ++) {
+ _RS_ASSERT_EQU((*v).arr[idx].i, gIntStart + y * gDimX + x + idx);
+ _RS_ASSERT_EQU((*v).arr[idx].l, gLongStart + y * gDimX + x + idx);
+ }
+ }
+ }
+
+ if (failed) {
+ rsDebug("small_struct_2 test FAILED", 0);
+ rsSendToClientBlocking(RS_MSG_TEST_FAILED);
+ }
+ else {
+ rsDebug("small_struct_2 test PASSED", 0);
+ rsSendToClientBlocking(RS_MSG_TEST_PASSED);
+ }
+}
+
+small_struct_2 RS_KERNEL setStruct(int x, int y) {
+ small_struct_2 output;
+ output.i = gIntStart + y * gDimX + x;
+ output.l = gLongStart + y * gDimX + x;
+ return output;
+}
+
+struct_of_struct_2 RS_KERNEL setArrayOfStruct(int x, int y) {
+ struct_of_struct_2 output;
+ for (int idx = 0; idx < ARRAY_LEN; idx ++) {
+ output.arr[idx].i = gIntStart + y * gDimX + x + idx;
+ output.arr[idx].l = gLongStart + y * gDimX + x + idx;
+ }
+ return output;
+}
diff --git a/tests/java_api/RsTest/src/com/android/rs/test/struct_field_simple.rs b/tests/java_api/RsTest/src/com/android/rs/test/struct_field_simple.rs
new file mode 100644
index 0000000..fb5ccbd
--- /dev/null
+++ b/tests/java_api/RsTest/src/com/android/rs/test/struct_field_simple.rs
@@ -0,0 +1,31 @@
+#include "shared.rsh"
+
+struct Simple {
+ int I;
+ long L;
+};
+
+struct Simple simple;
+
+void checkSimple(int argI, long argL) {
+ bool failed = false;
+
+ rsDebug("argI ", argI);
+ rsDebug("simple.I ", simple.I);
+ rsDebug("argL.lo ", (unsigned)argL & ~0U);
+ rsDebug("simple.L.lo", (unsigned)simple.L & ~0U);
+ rsDebug("argL.hi ", (unsigned)((ulong)argL >> 32));
+ rsDebug("simple.L.hi", (unsigned)((ulong)simple.L >> 32));
+
+ _RS_ASSERT(simple.I == argI);
+ _RS_ASSERT(simple.L == argL);
+
+ if (failed) {
+ rsDebug("struct_field_simple FAILED", 0);
+ rsSendToClientBlocking(RS_MSG_TEST_FAILED);
+ }
+ else {
+ rsDebug("struct_field_simple PASSED", 0);
+ rsSendToClientBlocking(RS_MSG_TEST_PASSED);
+ }
+}