/*
* compile with GCC 3.3.2 on s390-ibm-linux
* options: -O3
*
* instruction 61 and 71 will be switched by the scheduler, although they
* access overlapping memory
*
(insn 71 317 72 2 ff1f1500 (parallel [
(set (reg/v:SI 53)
(zero_extract:SI (mem/f:QI (plus:SI (reg/f:SI 34 %fp)
(const_int 96 [0x60])) [9 S1 A16])
(const_int 15 [0xf])
(const_int 0 [0x0])))
(clobber (reg:CC 33 %cc))
]) 89 {*extracthi} (insn_list 317 (nil))
(expr_list:REG_UNUSED (reg:CC 33 %cc)
(nil)))
(insn 61 67 63 2 ff1f1500 (set (mem/s:QI (plus:SI (reg/f:SI 34 %fp)
(const_int 97 [0x61])) [0 <variable>.string_2+1 S1 A8])
(mem/s:QI (plus:SI (reg/v/f:SI 49)
(const_int 3 [0x3])) [0 <variable>.mem2.string_2+1 S1 A8])) 59
{movqi} (insn_list 56 (insn_list:REG_DEP_OUTPUT 317
(insn_list:REG_DEP_ANTI 312 (insn_list:REG_DEP_ANTI 315 (nil)))))
(nil))
* The reason is probably in sched_analyze_2 which does not handle zero_extract
* correctly. It just hands the (mem:QI ...) subexpression to another
* incarnation of sched_analyze_2. The fact that 2 bytes were accessed is lost.
*
*/
typedef struct {
char string_2 [2];
} Char2;
typedef struct {
char string_4 [4];
} Char4;
typedef struct
{
void *mem4;
void *mem5;
Char4 mem6;
Char2 mem7;
Char2 mem8;
} Type2;
typedef struct {
Char2 mem1;
Char2 mem2;
Char2 mem3;
} Type1;
typedef void *Pointer;
unsigned char Erwin
(
Type2 *par1,
Type1 *par2,
Type1 *par3,
Type1 **par4,
Char2 **par5,
unsigned char *par6,
Char4 *par7
)
{
int var1;
Pointer var2;
Pointer var3;
Pointer var4;
int var5;
int var6;
int var7;
unsigned short var8;
Char2 var9;
Char2 var10;
unsigned char var11;
var2 = (Pointer) par2;
var4 = (Pointer) par2;
var11 = 0;
while ((var2 < par3) && (!var11))
{
if (memcmp( (Char2 *) var2, &par1->mem7, sizeof(Char2)) == 0)
{
*par4 = (Type1 *) var2;
((Char2 * ) &var8)->string_2[0] = ((Type1 *) var2)->mem2.string_2[0];;
((Char2 * ) &var8)->string_2[1] = ((Type1 *) var2)->mem2.string_2[1];;
var2 = (Pointer) ((char *) var2 + ((sizeof (Type1) - sizeof
(Char2))));
var3 = var2;
var5 = 0;
var6 = ((int) var8) / sizeof(Char2);
while (var5 != var6)
{
var7 = (var5 + var6) / sizeof(Char2);
var2 = ( (Pointer) ( (char *) (var3) + ((var7 * sizeof
(Char2))) ) );
var1 = memcmp ( (Char2 *) var2, &par1->mem8, sizeof(Char2));
if (var1 < 0)
{
var5 = var7 + 1;
}
else if (var1 > 0)
{
var6 = var7;
}
else
{
var6 = var7;
var5 = var7;
}
}
if ( var1 == 0)
{
var11 = (!0);
*par5 = ((Char2 *) var2);
if (( (Pointer) ( (char *) (var2) + (sizeof(Char2)) ) ) == par3)
{
*par6 = (!0);
if (( (Pointer) ( (char *) (*par4) +
((sizeof (Type1) - sizeof (Char2))) ) ) == var2)
{
if (var4 == *par4)
{
memset(&var9, 0x00, sizeof(Char2));
memset(&var10, 0x00, sizeof(Char2));
}
else
{
memcpy (&var9, var4, sizeof(Char2));
*((Char2 * ) &var8) = ((Type1 *) var4)->mem2;;
var2 = ((Pointer) ((char *) var4 + ((var8 +
(sizeof (Type1) - sizeof (Char2)) - sizeof
(Char2))) ) );
memcpy (&var10, var2, sizeof(Char2));
}
}
else
{
var2 = ( (Pointer) ( (char *) (var2) - (sizeof(Char2)) ) );
memcpy (&var10, var2, sizeof(Char2));
var9 = par1->mem7;
}
memcpy(&(par7->string_4[0]), &var9, sizeof(Char2));
memcpy(&(par7->string_4[2]), &var10, sizeof(Char2));
}
else
{
*par6 = 0;
}
}
else
{
var11 = 0;
break;
}
}
else
{
var4 = var2;
*((Char2 * ) &var8) = ((Type1 *) var2)->mem2;;
var2 = ( (Pointer) ( (char *) (var2) + ((var8 +
(sizeof (Type1) - sizeof (Char2)) )) ) );
}
}
return(var11);
}
--
Summary: Scheduler does not handle zero_extract correctly
Product: gcc
Version: 3.3.2
Status: UNCONFIRMED
Severity: normal
Priority: P2
Component: rtl-optimization
AssignedTo: unassigned at gcc dot gnu dot org
ReportedBy: Erwin dot Unruh at fujitsu-siemens dot com
CC: gcc-bugs at gcc dot gnu dot org
GCC build triplet: sparc-sun-solaris2.8
GCC host triplet: sparc-sun-solaris2.8
GCC target triplet: s390-ibm-linux
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=23650