11320 – [3.3 regression] Scheduler bug (original) (raw)

Description Andreas Schwab 2003-06-25 14:30:23 UTC

Register r14 is used for two different values at the same time.

$ cat http_core.c int strcmp (const char *, const char *); int printf (const char *, ...); int ap_standalone; const char * ap_check_cmd_context (void *a, int b) { return 0; }

const char * server_type (void *a, void *b, char *arg) { const char *err = ap_check_cmd_context (a, 0x01|0x02|0x04|0x08|0x10); if (err) return err;

if (!strcmp (arg, "inetd")) ap_standalone = 0; else if (!strcmp (arg, "standalone")) { // printf ("standalone"); ap_standalone = 1; } else return "ServerType must be either 'inetd' or 'standalone'";

return 0; }

int main () { server_type (0, 0, "standalone"); } $ gcc -O2 -g http_core.c $ ./a.out Segmentation fault

addl r14 = @ltoffx(ap_standalone#), r1 
;; 
.mii 
ld8.mov r15 = [r14], ap_standalone# 
addl r14 = @ltoffx(.LC2), r1 
;; 
(p7) addl r14 = 1, r0		<--- r14 clobbered 
;; 
.mii 
(p7) st4 [r15] = r14 
nop.i 0 
nop.i 0 
.mbb 
ld8.mov r14 = [r14], .LC2	<--- crash 

Workaround: compile with -fno-sched-interblock or -fno-if-conversion2 or -fno-sched-spec or -fno-schedule-insns.

Comment 1 Eric Botcazou 2003-07-06 11:25:20 UTC

Confirmed on gcc version 3.3.1 20030703 (prerelease).

Preliminary investigations suggest that the culprit is the machine dependent reorganisation pass, which swaps

(jump_insn 82 88 122 3 0x401b54c0 (set (pc) (if_then_else (eq (reg:BI 262 p6 [361]) (const_int 0 [0x0])) (label_ref 100) (pc))) 214 {*br_true} (insn_list 81 (nil)) (expr_list:REG_DEAD (reg:BI 262 p6 [361]) (expr_list:REG_BR_PROB (const_int 5000 [0x1388]) (nil))))

(insn 96 122 159 4 0x401b54c0 (set (reg/f:DI 14 r14 [340]) (lo_sum:DI (reg:DI 14 r14 [365]) (symbol_ref/f:DI ("*.LC2")))) 12 {load_symptr_low} (nil) (expr_list:REG_EQUAL (symbol_ref/f:DI (".LC2")) (nil)))

to produce

.mbb
ld8 r14 = [r14]
(p7) br.cond.dptk .L4

I don't know enough of IA-64 to say whether swapping back the instructions in the assembly file is sufficient, or whether they should not have ended up in the same bundle in the first place.

Comment 2 Andreas Schwab 2003-07-08 13:56:23 UTC

Replacing: .mii (p7) st4 [r15] = r14 nop.i 0 nop.i 0 .mbb ld8.mov r14 = [r14], .LC2 (p7) br.cond.dptk .L5 br .L2 ;; with: .mib (p7) st4 [r15] = r14 nop.i 0 (p7) br.cond.dptk .L5 .mbb ld8.mov r14 = [r14], .LC2 nop.b 0 br .L2 ;; (thus effectively undoing the swapping) produces working code.

Comment 3 Eric Botcazou 2003-07-10 08:05:30 UTC

Thanks. I think I've found the root of the problem and even a possible solution, but I'll need your help for testing because I don't have access to IA-64 hardware.

Comment 4 Mark Mitchell 2003-07-11 23:09:50 UTC

Postponed until GCC 3.3.2; IA64 is not a primary platform.

Comment 5 Eric Botcazou 2003-07-12 07:45:24 UTC

*** Bug 11399 has been marked as a duplicate of this bug. ***

Comment 11 Bernd Schmidt 2011-07-15 13:20:17 UTC

Author: bernds Date: Fri Jul 15 13:20:10 2011 New Revision: 176315

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=176315 Log: Revert 2003-07-10 Eric Botcazou <ebotcazou@libertysurf.fr> PR rtl-optimization/11320 * sched-int.h (struct deps) [reg_conditional_sets]: New field. (struct sched_info) [compute_jump_reg_dependencies]: New prototype. * sched-deps.c (sched_analyze_insn) [JUMP_INSN]: Update call to current_sched_info->compute_jump_reg_dependencies. Record which registers are used and which registers are set by the jump. Clear deps->reg_conditional_sets after a barrier. Set deps->reg_conditional_sets if the insn is a COND_EXEC. Clear deps->reg_conditional_sets if the insn is not a COND_EXEC. (init_deps): Initialize reg_conditional_sets. (free_deps): Clear reg_conditional_sets. * sched-ebb.c (compute_jump_reg_dependencies): New prototype. Mark registers live on entry of the fallthrough block and conditionally set as set by the jump. Mark registers live on entry of non-fallthrough blocks as used by the jump. * sched-rgn.c (compute_jump_reg_dependencies): New prototype. Mark new parameters as unused.

Modified: trunk/gcc/ChangeLog trunk/gcc/modulo-sched.c trunk/gcc/sched-deps.c trunk/gcc/sched-ebb.c trunk/gcc/sched-int.h trunk/gcc/sched-rgn.c