A Q reg can be built by a vector compare or by vand(Vu, Rt), and
those reach the predicate register through independent code paths. Check
that both select the same byte lanes, so a byte-order mistake in either
one is caught.

The input alternates every eight lanes: a flatter pattern
stays unchanged when predicate bytes are permuted and hides the bug.

Signed-off-by: Brian Cain <[email protected]>
---
 tests/tcg/hexagon/hvx_misc.c | 45 ++++++++++++++++++++++++++++++++++++
 1 file changed, 45 insertions(+)

diff --git a/tests/tcg/hexagon/hvx_misc.c b/tests/tcg/hexagon/hvx_misc.c
index 32a3661a86f..225666137c9 100644
--- a/tests/tcg/hexagon/hvx_misc.c
+++ b/tests/tcg/hexagon/hvx_misc.c
@@ -181,6 +181,50 @@ static void test_store_unaligned(void)
     check_output_w(__LINE__, 2);
 }
 
+/*
+ * A Q register can be built either by a vector compare or by vand(Vu, Rt).
+ * Those are two independent code paths onto the same predicate-register
+ * layout, so cross-check that they select exactly the same byte lanes.
+ * A byte-order mistake in either one shows up here as a mismatch.
+ *
+ * The input pattern has to vary across 8-lane blocks, otherwise a predicate
+ * whose bytes are permuted still selects the same lanes and the mismatch is
+ * invisible.
+ */
+static void test_qreg_alias(void)
+{
+    HVX_Vector *pcmp = (HVX_Vector *)&output[0];
+    HVX_Vector *pand = (HVX_Vector *)&output[1];
+    HVX_Vector input;
+    HVX_Vector ones;
+    HVX_VectorPred qcmp;
+    HVX_VectorPred qand;
+
+    for (int i = 0; i < BUFSIZE; i++) {
+        /*
+         * Build 0/1 per byte, alternating every 8 lanes, so that "!= 0" and
+         * "low bit set" describe the same lanes.  Then form one predicate
+         * with a compare and the other with vand(Vu, Rt), store 0xff through
+         * each, and require the two result vectors to be identical.
+         */
+        for (int j = 0; j < MAX_VEC_SIZE_BYTES; j++) {
+            expect[0].ub[j] = ((j >> 3) + i) & 1;
+        }
+        memcpy(&input, &expect[0], sizeof(MMVector));
+        memset(output, 0, 2 * sizeof(MMVector));
+
+        ones = Q6_V_vsplat_R(0xffffffff);
+        qcmp = Q6_Q_vcmp_gt_VubVub(input, Q6_V_vzero());
+        qand = Q6_Q_vand_VR(input, 0x01010101);
+        Q6_vmem_QRIV(qcmp, pcmp, ones);
+        Q6_vmem_QRIV(qand, pand, ones);
+
+        for (int j = 0; j < MAX_VEC_SIZE_BYTES; j++) {
+            check(__LINE__, i, j, output[0].ub[j], output[1].ub[j]);
+        }
+    }
+}
+
 static void test_masked_store(bool invert)
 {
     void *p0 = buffer0;
@@ -579,6 +623,7 @@ int main()
     test_store_unaligned();
     test_masked_store(false);
     test_masked_store(true);
+    test_qreg_alias();
     test_new_value_store();
     test_max_temps();
 
-- 
2.34.1

Reply via email to