Add a test for vex ppc64 code generation bug fixed by vex r1739

(When generating 64-bit code, ensure that any addresses used in 4 or 8
byte loads or stores of the form reg+imm have the lowest 2 bits of imm
set to zero, so that they can safely be used in ld/ldu/lda/std/stdu
instructions.)



git-svn-id: svn://svn.valgrind.org/valgrind/trunk@6645
This commit is contained in:
Julian Seward 2007-03-12 02:10:23 +00:00
parent 34454d5464
commit 3235d88de8
5 changed files with 84 additions and 1 deletions

View File

@ -6,11 +6,12 @@ EXTRA_DIST = $(noinst_SCRIPTS) \
jm-fp.stderr.exp jm-fp.stdout.exp jm-fp.vgtest \
jm-vmx.stderr.exp jm-vmx.stdout.exp jm-vmx.vgtest \
lsw.stderr.exp lsw.stdout.exp lsw.vgtest \
std_reg_imm.vgtest std_reg_imm.stderr.exp std_reg_imm.stdout.exp \
round.stderr.exp round.stdout.exp round.vgtest \
twi_tdi.stderr.exp twi_tdi.stdout.exp twi_tdi.vgtest
check_PROGRAMS = \
jm-insns lsw round twi_tdi
jm-insns lsw round std_reg_imm twi_tdi
AM_CFLAGS = $(WERROR) -Winline -Wall -Wshadow -g -I$(top_srcdir)/include \
@FLAG_M64@

View File

@ -0,0 +1,79 @@
/*
This is a regression test for the following problem, noticed by
Greg Parker:
vex ppc64 generates bad code for instruction sequences like this:
li r0, 2
stdx r3, r1, r0
gcc emits code like this when manipulating packed structures
with 8-byte fields on 2-byte boundaries.
First, vex's optimizer substitutes a constant 0x2 for r0:
------ IMark(0x100000F34, 4) ------
PUT(1024) = 0x100000F34:I64
t3 = GET:I64(24)
t14 = GET:I64(8)
t13 = Add64(t14,0x2:I64)
STbe(t13) = t3
Then instruction selection chooses `std` with an index not divisible by 4:
-- STbe(Add64(GET:I64(8),0x2:I64)) = GET:I64(24)
ldz %vR22,8(%r31)
ldz %vR23,24(%r31)
std %vR23,2(%vR22)
Finally, the assembler silently strips the index&3 part,
because `std` can't encode that:
std %r6,2(%r5)
F8 C5 00 00
...but 0xF8C50000 is `std r6, 0(r5)`, which writes to the wrong address.
*/
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
typedef
struct __attribute__ ((__packed__)) {
char before[2];
unsigned long long int w64;
char after[6];
}
T;
void foo (T* t, unsigned long long int w)
{
__asm__ __volatile__(
"stdx %0,%1,%2"
: : "b"(w), "b"(t), "b"(2) : "memory"
);
}
int main ( void )
{
T* t;
unsigned char* p;
int i;
assert(sizeof(T) == 16);
t = calloc(sizeof(T),1);
assert(t);
/* check t is 8-aligned. This causes the write done by 'foo' to be
misaligned by 2 as desired, triggering the bug. */
assert(0 == (((unsigned long)t) & 7));
foo(t, 0x1122334455667788);
p = (unsigned char*)t;
for (i = 0; i < 16; i++)
if (p[i] == 0)
printf("..");
else
printf("%02x", (int)p[i]);
printf("\n");
return 0;
}

View File

View File

@ -0,0 +1 @@
....1122334455667788............

View File

@ -0,0 +1,2 @@
prog: std_reg_imm
vgopts: -q