r147980 [1] breaks stdargs on alpha [2]: FAIL: gcc.c-torture/execute/stdarg-1.c execution, -O3 -fomit-frame-pointer FAIL: gcc.c-torture/execute/stdarg-1.c execution, -O3 -g FAIL: gcc.c-torture/execute/stdarg-4.c execution, -O1 FAIL: gcc.c-torture/execute/stdarg-4.c execution, -O2 FAIL: gcc.c-torture/execute/stdarg-4.c execution, -O3 -fomit-frame-pointer FAIL: gcc.c-torture/execute/stdarg-4.c execution, -O3 -g FAIL: gcc.c-torture/execute/stdarg-4.c execution, -Os ... FAIL: gcc.dg/tree-ssa/stdarg-2.c scan-tree-dump stdarg "f15: va_list escapes 1, needs to save all GPR units and all FPR units"
Before new SRA, stdarg dump for gcc.dg/tree-ssa/stdarg-2.c, f15 () showed: --cut here-- va_list escapes in # .MEMD.2039_12 = VDEF <.MEMD.2039_2> apD.2040 = apD.1263; f15: va_list escapes 1, needs to save all GPR units and all FPR units. --cut here-- With new SRA (r147980): bb2 will be executed at most once for each va_start in bb2 bb3 will be executed at most once for each va_start in bb2 f15: va_list escapes 0, needs to save 8 GPR units and 0 FPR units. The last OK testresults were from r147610 [3] and started to fail in r148747 [4] The problem can be triggered by compiling following test (distilled from stdarg-2.c) with a crosscompiler to alpha-linux-gnu: --cut here-- typedef __builtin_va_list __gnuc_va_list; typedef __gnuc_va_list va_list; long x; inline void __attribute__((always_inline)) f15_1 (va_list ap) { x = __builtin_va_arg(ap,long); } void f15 (int i, ...) { va_list ap; __builtin_va_start(ap,i); f15_1 (ap); __builtin_va_end(ap); } --cut here-- gcc -O2 -fdump-tree-stdarg. Runtime failure will be triggered by following test (sorry for the debug printk's): --cut here-- # 1 "t.c" # 1 "<built-in>" # 1 "<command-line>" # 1 "t.c" # 1 "/space/uros/gcc-build-44/gcc/include/stdarg.h" 1 3 4 # 40 "/space/uros/gcc-build-44/gcc/include/stdarg.h" 3 4 typedef __builtin_va_list __gnuc_va_list; # 102 "/space/uros/gcc-build-44/gcc/include/stdarg.h" 3 4 typedef __gnuc_va_list va_list; # 2 "t.c" 2 extern void abort (void); int foo_arg; long x; void foo (int v, va_list ap) { printf ("__base = %p\n", ap.__base); printf ("__offset = %i\n", ap.__offset); switch (v) { case 5: foo_arg = __builtin_va_arg(ap,int); printf ("foo_arg = %i\n", foo_arg); break; default: abort (); } printf ("__base = %p\n", ap.__base); printf ("__offset = %i\n", ap.__offset); } void __attribute__((noinline)) f4 (int i, ...) { va_list ap; __builtin_va_start(ap,i); printf ("f4 __base = %p\n", ap.__base); printf ("f4 __offset = %i\n", ap.__offset); x = __builtin_va_arg(ap,double); foo (i, ap); printf ("f4 __base = %p\n", ap.__base); printf ("f4 __offset = %i\n", ap.__offset); __builtin_va_end(ap); } int main (void) { f4 (5, 16.0, 128); if (x != 16 || foo_arg != 128) abort (); return 0; } --cut here-- foo_arg will be 0 at the final test. [1] http://gcc.gnu.org/ml/gcc-cvs/2009-05/msg00959.html [2] http://gcc.gnu.org/ml/gcc-testresults/2009-08/msg01508.html [3] http://gcc.gnu.org/ml/gcc-testresults/2009-05/msg01614.html [4] http://gcc.gnu.org/ml/gcc-testresults/2009-06/msg01912.html -- Summary: [4.5 Regression] r147980 (New SRA) breaks stdargs Product: gcc Version: 4.5.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: tree-optimization AssignedTo: unassigned at gcc dot gnu dot org ReportedBy: ubizjak at gmail dot com GCC target triplet: alphaev68-unknown-linux-gnu http://gcc.gnu.org/bugzilla/show_bug.cgi?id=41089