summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Gross <dgross@google.com>2017-03-29 20:55:34 +0000
committerDavid Gross <dgross@google.com>2017-03-29 15:20:54 -0700
commit4d95f4edfa74a1023ba77e2745ee24102f97e656 (patch)
treea9ebb03fb3932d4a2439c813a76bb6c8b36851d1
parentb82642f7a25c67923fa1fe2e0cbf71996aae8c99 (diff)
downloadrs-4d95f4edfa74a1023ba77e2745ee24102f97e656.tar.gz
Add regression tests for 32-bit x86 struct layout bug fixes.
Bug: http://b/29154200 Bug: http://b/28070272 Test: (aosp_x86_64-eng emulator, full_fugu-eng, aosp_angler-eng) x (RsTest 32-bit, RsTest 64-bit) - Tried ( modified slang, unmodified bcc) and ( modified slang, modified bcc) - "Modified bcc" is a forthcoming bcc change to turn off old struct layout fixes, and to verify that front end (Module) and back end (TargetMachine) agree on the layout of every exported struct type. https://android-review.googlesource.com/#/c/358954 - "Modified slang" is a forthcoming slang change to add explicit padding to struct types, thereby fixing the struct layout bugs. https://android-review.googlesource.com/#/c/359135/ Change-Id: I393230bd9a8d5e87f0e3a94a2fa2bf6e89d00929 (cherry picked from commit 08012d1f91f78dcacdffa298d9bf3414dea75209)
-rw-r--r--tests/java_api/RsTest/src/com/android/rs/test/RSTestCore.java3
-rw-r--r--tests/java_api/RsTest/src/com/android/rs/test/UT_bitfield.java44
-rw-r--r--tests/java_api/RsTest/src/com/android/rs/test/UT_small_struct.java2
-rw-r--r--tests/java_api/RsTest/src/com/android/rs/test/UT_small_struct_2.java70
-rw-r--r--tests/java_api/RsTest/src/com/android/rs/test/UT_struct_field_simple.java83
-rw-r--r--tests/java_api/RsTest/src/com/android/rs/test/bitfield.rs87
-rw-r--r--tests/java_api/RsTest/src/com/android/rs/test/small_struct.rs3
-rw-r--r--tests/java_api/RsTest/src/com/android/rs/test/small_struct_2.rs70
-rw-r--r--tests/java_api/RsTest/src/com/android/rs/test/struct_field_simple.rs31
9 files changed, 393 insertions, 0 deletions
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 0583cb7e..ac8dad5c 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 @@ public class RSTestCore {
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 00000000..4ba4b693
--- /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 4f23b5d2..ca96b61b 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.Allocation;
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 00000000..7f03b44f
--- /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 00000000..748c2a35
--- /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 00000000..bce32f7d
--- /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 9aa9677c..4c1f437f 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 @@ static long gLongStart = 0x12345678abcdef12;
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 00000000..f56f9994
--- /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 00000000..fb5ccbda
--- /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);
+ }
+}