[svn.haxx.se] · SVN Dev · SVN Users · SVN Org · TSVN Dev · TSVN Users · Subclipse Dev · Subclipse Users · this month's index

random-test failure on powerpc64le and x86_64

From: Alan Modra <amodra_at_gmail.com>
Date: Sat, 9 Aug 2014 23:25:09 +0930

Using current git sources compiled with gcc-4.9.1 or mainline gcc at
-O3 results in failure of random-test.

On powerpc64le we see
PASS: random-test 1: random delta test
svn_tests: E200006: mismatch at position xxxxx
FAIL: random-test 2: random combine delta test

x86_64 gives
PASS: random-test 1: random delta test
svn_tests: E200006: Test crashed (run in debugger with '--allow-segfaults')
FAIL: random-test 2: random combine delta test

After some digging, I narrowed the failure down to
subversion/libsvn_delta/text_delta.c, and the specific -O3 options
causing the failure to -ftree-loop-vectorize -fvect-cost-model=dynamic.
At first I thought I'd found a vectorizer bug, but the real problem is
a bug in the source, specifically this line in patterning_copy:

      *(apr_uint32_t *)(target) = *(apr_uint32_t *)(source);

Quoting from ISO/IEC 9899:1999
6.3.2.3 Pointers
...
7 A pointer to an object or incomplete type may be converted to a
pointer to a different object or incomplete type. If the resulting
pointer is not correctly aligned for the pointed-to type, the behavior
is undefined.

So here we have undefined behaviour if "source" and "target" are not
4-byte aligned.. Fixed as follows.

Index: subversion/libsvn_delta/text_delta.c
===================================================================
--- subversion/libsvn_delta/text_delta.c (revision 1616755)
+++ subversion/libsvn_delta/text_delta.c (working copy)
@@ -669,14 +669,15 @@
 
 #if SVN_UNALIGNED_ACCESS_IS_OK
 
- if (source + sizeof(apr_uint32_t) <= target)
+ typedef apr_uint32_t __attribute__ ((aligned (1))) unaligned32;
+ if (source + sizeof(unaligned32) <= target)
     {
       /* Source and target are at least 4 bytes apart, so we can copy in
        * 4-byte chunks. */
- for (; source + sizeof(apr_uint32_t) <= end;
- source += sizeof(apr_uint32_t),
- target += sizeof(apr_uint32_t))
- *(apr_uint32_t *)(target) = *(apr_uint32_t *)(source);
+ for (; source + sizeof(unaligned32) <= end;
+ source += sizeof(unaligned32),
+ target += sizeof(unaligned32))
+ *(unaligned32 *)target = *(unaligned32 *)source;
     }
 
 #endif

-- 
Alan Modra
Australia Development Lab, IBM
Received on 2014-08-09 16:02:09 CEST

This is an archived mail posted to the Subversion Dev mailing list.

This site is subject to the Apache Privacy Policy and the Apache Public Forum Archive Policy.