http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53827
Bug #: 53827 Summary: [alpha]: Invalid insn scheduling in sched1 pass Classification: Unclassified Product: gcc Version: 4.8.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: rtl-optimization AssignedTo: unassig...@gcc.gnu.org ReportedBy: ubiz...@gmail.com Following testcase exposes a bug in sched1 pass: --cut here-- #ifndef MAX_OFFSET #define MAX_OFFSET (sizeof (long long)) #endif #ifndef MAX_COPY #define MAX_COPY 15 #endif #ifndef MAX_EXTRA #define MAX_EXTRA (sizeof (long long)) #endif #define MAX_LENGTH (MAX_OFFSET + MAX_COPY + MAX_EXTRA) static union { char buf[MAX_LENGTH]; long long align_int; long double align_fp; } u; void reset (void); void check (int off, int len, int ch); int test () { int off; char *p; reset (); p = memset (u.buf + 1, '\0', 15); check (1, 15, '\0'); return 0; } --cut here-- This bug can be triggered with a crosscompiler from x86_64-pc-linux-gnu to alpha-linux-gnu target. ~/gcc-build-alpha/gcc/cc1 -O2 -mcpu=ev6 test: .frame $30,16,$26,0 .mask 0x4000000,-16 ldgp $29,0($27) # 39 *prologue_ldgp_1 [length = 4] $test..ng: lda $30,-16($30) # 41 *adddi_internal/2 [length = 4] stq $26,0($30) # 42 *movdi/9 [length = 4] .prologue 1 jsr $26,reset # 5 *call_osf_1/3 [length = 16] ldgp $29,0($26) lda $1,u # 6 *movdi/7 [length = 4] lda $16,1($31) # 22 *movdi/2 [length = 4] lda $17,15($31) # 23 *movdi/2 [length = 4] mov $31,$18 # 24 *movdi/1 [length = 4] ldq_u $3,8($1) # 7 *movdi/8 [length = 4] ldq_u $2,1($1) # 8 *movdi/8 [length = 4] lda $4,1($1) # 9 *adddi_internal/2 [length = 4] >>> stb $31,15($1) # 20 *movqi/4 [length = 4] mskqh $3,$4,$3 # 10 mskxh [length = 4] mskql $2,$4,$2 # 11 mskxl [length = 4] >>> stq_u $3,8($1) # 12 *movdi/9 [length = 4] stq_u $2,1($1) # 13 *movdi/9 [length = 4] stb $31,9($1) # 14 *movqi/4 [length = 4] stb $31,10($1) # 15 *movqi/4 [length = 4] stb $31,11($1) # 16 *movqi/4 [length = 4] stb $31,12($1) # 17 *movqi/4 [length = 4] stb $31,13($1) # 18 *movqi/4 [length = 4] stb $31,14($1) # 19 *movqi/4 [length = 4] jsr $26,check # 25 *call_osf_1/3 [length = 16] ldgp $29,0($26) ldq $26,0($30) # 45 *movdi/8 [length = 4] mov $31,$0 # 30 *movdi/1 [length = 4] lda $30,16($30) # 47 *adddi_internal/2 [length = 4] ret $31,($26),1 # 48 *return_internal [length = 4] .end test (insn 20) has been moved above (insn 12) in sched1 pass, although (insn 12) stores DImode value to $1+8. For reference, (insn 12) is defined as: (insn 12 11 13 2 (set (mem/c:DI (and:DI (plus:DI (reg/f:DI 71) (const_int 8 [0x8])) (const_int -8 [0xfffffffffffffff8])) [0 S8 A64]) (reg:DI 73)) t.c:31 225 {*movdi} (expr_list:REG_DEAD (reg:DI 73) (nil))) and (insn 20): (insn 20 9 10 2 (set (mem/c:QI (plus:DI (reg/f:DI 71) (const_int 15 [0xf])) [0 MEM[(void *)&u + 1B]+14 S1 A8]) (const_int 0 [0])) t.c:31 228 {*movqi} (expr_list:REG_DEAD (reg/f:DI 71) (nil))) This is the only failure in gcc.c-torture/execute/memset-2.c execution failure (and probably also in gcc.c-torture/execute/builtins/memset-chk.c execution failure) [1]. It looks like off-by-one somewhere in the sched1 pass to me, please note that other insns with offsets less than 15 are not moved. [1] http://gcc.gnu.org/ml/gcc-testresults/2012-07/msg00017.html