Message ID | 006d01d86d00$777e67b0$667b3710$@nextmovesoftware.com |
---|---|
State | New |
Headers | show |
Series | [PING] PR middle-end/95126: Expand small const structs as immediate constants | expand |
This breaks Ada on aarch64 in stage3, probably a miscompiled stage2 compiler. For example: /opt/gcc/gcc-20220605/Build/./prev-gcc/xgcc -B/opt/gcc/gcc-20220605/Build/./prev-gcc/ -B/usr/aarch64-suse-linux/bin/ -B/usr/aarch64-suse-linux/bin/ -B/usr/aarch64-suse-linux/lib/ -isystem /usr/aarch64-suse-linux/include -isystem /usr/aarch64-suse-linux/sys-include -fchecking=1 -c -g -O2 -fchecking=1 -gnatpg -gnata -W -Wall -nostdinc -I- -I. -Iada/generated -Iada -I../../gcc/ada -Iada/libgnat -I../../gcc/ada/libgnat -Iada/gcc-interface -I../../gcc/ada/gcc-interface ../../gcc/ada/spark_xrefs.adb -o ada/spark_xrefs.o +===========================GNAT BUG DETECTED==============================+ | 13.0.0 20220605 (experimental) [master ad6919374be] (aarch64-suse-linux) | | Assert_Failure failed precondition from sinfo-nodes.ads:5419 | | Error detected at types.ads:53:28 | | Compiling ../../gcc/ada/spark_xrefs.adb | | Please submit a bug report; see https://gcc.gnu.org/bugs/ . | | Use a subject line meaningful to you and us to track the bug. | | Include the entire contents of this bug box in the report. | | Include the exact command that you entered. | | Also include sources listed below. | +==========================================================================+
Andreas Schwab <schwab@linux-m68k.org> writes: > This breaks Ada on aarch64 in stage3, probably a miscompiled stage2 > compiler. For example: > > /opt/gcc/gcc-20220605/Build/./prev-gcc/xgcc > -B/opt/gcc/gcc-20220605/Build/./prev-gcc/ -B/usr/aarch64-suse-linux/bin/ > -B/usr/aarch64-suse-linux/bin/ -B/usr/aarch64-suse-linux/lib/ -isystem > /usr/aarch64-suse-linux/include -isystem > /usr/aarch64-suse-linux/sys-include -fchecking=1 -c -g -O2 -fchecking=1 > -gnatpg -gnata -W -Wall -nostdinc -I- -I. -Iada/generated -Iada > -I../../gcc/ada -Iada/libgnat -I../../gcc/ada/libgnat -Iada/gcc-interface > -I../../gcc/ada/gcc-interface ../../gcc/ada/spark_xrefs.adb -o > ada/spark_xrefs.o > +===========================GNAT BUG DETECTED==============================+ > | 13.0.0 20220605 (experimental) [master ad6919374be] (aarch64-suse-linux) | > | Assert_Failure failed precondition from sinfo-nodes.ads:5419 | > | Error detected at types.ads:53:28 | > | Compiling ../../gcc/ada/spark_xrefs.adb | > | Please submit a bug report; see https://gcc.gnu.org/bugs/ . | > | Use a subject line meaningful to you and us to track the bug. | > | Include the entire contents of this bug box in the report. | > | Include the exact command that you entered. | > | Also include sources listed below. | > +==========================================================================+ Confirmed: this also happens on i386-pc-solaris2.11, sparc-sun-solaris2.11, and x86_64-pc-linux-gnu.
Hi Rainer (and Andreas), My sincere apologies for the breakage. I'm currently regression testing a solution to the ICEs introduced by my "small const struct" patch, which fingers-crossed might also fix this Ada bootstrap. For a while when Rainer also reported the bootstrap failure is visible, on x86_64-pc-linux-gnu, I thought I'd be able to diagnose and fix the issue myself, but alas my --enable-languages="all" builds (still) fail earlier with: gcc -std=gnu99 -c -g -gnatpg -gnatwns -gnata -W -Wall -I- -I. -Iada/generated -Iada -I../../gcc/gcc/ada ../../gcc/gcc/ada/osint.adb -o ada/osint.o osint.adb:438:31: "strlen" not declared in "CRTL" osint.adb:441:14: "strncpy" not declared in "CRTL" osint.adb:675:21: "strlen" not declared in "CRTL" osint.adb:728:16: "Open_Append" is undefined osint.adb:1108:41: "int64" not declared in "CRTL" osint.adb:3144:28: "strlen" not declared in "CRTL" osint.adb:3147:11: "strncpy" not declared in "CRTL" The one experiment I'd like to be able to try, to investigate the cause/cure of this, is: diff --git a/gcc/calls.cc b/gcc/calls.cc index a4336c1..05fdd24 100644 --- a/gcc/calls.cc +++ b/gcc/calls.cc @@ -2177,7 +2177,7 @@ load_register_parameters (struct arg_data *args, int num_a VAR_DECL with a simple constructor, expand that constructor via a pseudo rather than read from (possibly misaligned) memory. PR middle-end/95126. */ - else if (nregs == 1 + else if (0 && nregs == 1 && partial == 0 && !args[i].pass_on_stack && VAR_P (tree_value) My "small const structs" patch affected code generation in three places, and identifying which of these is causing the miscompilation issue for gnat will help narrow down the problem, or worst case allow reverting less of the problematic patch. Again my deep apologies for the breakage. Hopefully the fix I'm testing will cure this as well (but an ICE is different symptom to a silent miscompilation). Sorry again, Roger -- > -----Original Message----- > From: Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE> > Sent: 05 June 2022 21:31 > To: Andreas Schwab <schwab@linux-m68k.org> > Cc: Roger Sayle <roger@nextmovesoftware.com>; gcc-patches@gcc.gnu.org > Subject: Re: [PING] PR middle-end/95126: Expand small const structs as > immediate constants > > Andreas Schwab <schwab@linux-m68k.org> writes: > > > This breaks Ada on aarch64 in stage3, probably a miscompiled stage2 > > compiler. For example: > > > > /opt/gcc/gcc-20220605/Build/./prev-gcc/xgcc > > -B/opt/gcc/gcc-20220605/Build/./prev-gcc/ > > -B/usr/aarch64-suse-linux/bin/ -B/usr/aarch64-suse-linux/bin/ > > -B/usr/aarch64-suse-linux/lib/ -isystem > > /usr/aarch64-suse-linux/include -isystem > > /usr/aarch64-suse-linux/sys-include -fchecking=1 -c -g -O2 > > -fchecking=1 -gnatpg -gnata -W -Wall -nostdinc -I- -I. -Iada/generated > > -Iada -I../../gcc/ada -Iada/libgnat -I../../gcc/ada/libgnat > > -Iada/gcc-interface -I../../gcc/ada/gcc-interface > > ../../gcc/ada/spark_xrefs.adb -o ada/spark_xrefs.o > > +===========================GNAT BUG > > +DETECTED==============================+ > > | 13.0.0 20220605 (experimental) [master ad6919374be] (aarch64-suse-linux) > | > > | Assert_Failure failed precondition from sinfo-nodes.ads:5419 | > > | Error detected at types.ads:53:28 | > > | Compiling ../../gcc/ada/spark_xrefs.adb | > > | Please submit a bug report; see https://gcc.gnu.org/bugs/ . | > > | Use a subject line meaningful to you and us to track the bug. | > > | Include the entire contents of this bug box in the report. | > > | Include the exact command that you entered. | > > | Also include sources listed below. | > > > +================================================================ > ===== > > +=====+ > > Confirmed: this also happens on i386-pc-solaris2.11, sparc-sun-solaris2.11, and > x86_64-pc-linux-gnu.
On Jun 06 2022, Roger Sayle wrote: > gcc -std=gnu99 -c -g -gnatpg -gnatwns -gnata -W -Wall -I- -I. > -Iada/generated -Iada -I../../gcc/gcc/ada ../../gcc/gcc/ada/osint.adb -o > ada/osint.o > osint.adb:438:31: "strlen" not declared in "CRTL" > osint.adb:441:14: "strncpy" not declared in "CRTL" > osint.adb:675:21: "strlen" not declared in "CRTL" > osint.adb:728:16: "Open_Append" is undefined > osint.adb:1108:41: "int64" not declared in "CRTL" > osint.adb:3144:28: "strlen" not declared in "CRTL" > osint.adb:3147:11: "strncpy" not declared in "CRTL" What's your bootstrap compiler?
Hi Andreas, > > gcc -std=gnu99 -c -g -gnatpg -gnatwns -gnata -W -Wall -I- -I. > > -Iada/generated -Iada -I../../gcc/gcc/ada ../../gcc/gcc/ada/osint.adb > > -o ada/osint.o > > osint.adb:438:31: "strlen" not declared in "CRTL" > > osint.adb:441:14: "strncpy" not declared in "CRTL" > > osint.adb:675:21: "strlen" not declared in "CRTL" > > osint.adb:728:16: "Open_Append" is undefined > > osint.adb:1108:41: "int64" not declared in "CRTL" > > osint.adb:3144:28: "strlen" not declared in "CRTL" > > osint.adb:3147:11: "strncpy" not declared in "CRTL" > > What's your bootstrap compiler? GNAT 4.8.5 20150623 (Red Hat 4.8.5-44) I'm currently investigating other options...
On Jun 06 2022, Roger Sayle wrote: > Hi Andreas, >> > gcc -std=gnu99 -c -g -gnatpg -gnatwns -gnata -W -Wall -I- -I. >> > -Iada/generated -Iada -I../../gcc/gcc/ada ../../gcc/gcc/ada/osint.adb >> > -o ada/osint.o >> > osint.adb:438:31: "strlen" not declared in "CRTL" >> > osint.adb:441:14: "strncpy" not declared in "CRTL" >> > osint.adb:675:21: "strlen" not declared in "CRTL" >> > osint.adb:728:16: "Open_Append" is undefined >> > osint.adb:1108:41: "int64" not declared in "CRTL" >> > osint.adb:3144:28: "strlen" not declared in "CRTL" >> > osint.adb:3147:11: "strncpy" not declared in "CRTL" >> >> What's your bootstrap compiler? > > GNAT 4.8.5 20150623 (Red Hat 4.8.5-44) That's very much out of date. In order to build GNAT, the Ada compiler, you need a working GNAT compiler (GCC version 5.1 or later).
Hi Roger, > My sincere apologies for the breakage. I'm currently regression testing a > solution to the ICEs introduced by my "small const struct" patch, which > fingers-crossed might also fix this Ada bootstrap. For a while when > Rainer also reported the bootstrap failure is visible, on > x86_64-pc-linux-gnu, > I thought I'd be able to diagnose and fix the issue myself, but alas my > --enable-languages="all" builds (still) fail earlier with: > > gcc -std=gnu99 -c -g -gnatpg -gnatwns -gnata -W -Wall -I- -I. > -Iada/generated -Iada -I../../gcc/gcc/ada ../../gcc/gcc/ada/osint.adb -o > ada/osint.o > osint.adb:438:31: "strlen" not declared in "CRTL" > osint.adb:441:14: "strncpy" not declared in "CRTL" > osint.adb:675:21: "strlen" not declared in "CRTL" > osint.adb:728:16: "Open_Append" is undefined > osint.adb:1108:41: "int64" not declared in "CRTL" > osint.adb:3144:28: "strlen" not declared in "CRTL" > osint.adb:3147:11: "strncpy" not declared in "CRTL" > > The one experiment I'd like to be able to try, to investigate the cause/cure > of this, is: > > diff --git a/gcc/calls.cc b/gcc/calls.cc > index a4336c1..05fdd24 100644 > --- a/gcc/calls.cc > +++ b/gcc/calls.cc > @@ -2177,7 +2177,7 @@ load_register_parameters (struct arg_data *args, int > num_a > VAR_DECL with a simple constructor, expand that constructor > via a pseudo rather than read from (possibly misaligned) > memory. PR middle-end/95126. */ > - else if (nregs == 1 > + else if (0 && nregs == 1 > && partial == 0 > && !args[i].pass_on_stack > && VAR_P (tree_value) > > My "small const structs" patch affected code generation in three places, and > identifying > which of these is causing the miscompilation issue for gnat will help narrow > down the > problem, or worst case allow reverting less of the problematic patch. I just tried this on i386-pc-solaris2.11: unfortunately, it made no difference. Rainer
Andreas Schwab <schwab@linux-m68k.org> writes: > On Jun 06 2022, Roger Sayle wrote: > >> gcc -std=gnu99 -c -g -gnatpg -gnatwns -gnata -W -Wall -I- -I. >> -Iada/generated -Iada -I../../gcc/gcc/ada ../../gcc/gcc/ada/osint.adb -o >> ada/osint.o >> osint.adb:438:31: "strlen" not declared in "CRTL" >> osint.adb:441:14: "strncpy" not declared in "CRTL" >> osint.adb:675:21: "strlen" not declared in "CRTL" >> osint.adb:728:16: "Open_Append" is undefined >> osint.adb:1108:41: "int64" not declared in "CRTL" >> osint.adb:3144:28: "strlen" not declared in "CRTL" >> osint.adb:3147:11: "strncpy" not declared in "CRTL" > > What's your bootstrap compiler? FWIW, I'm using GCC 9 (9.4.0 on Solaris/x86, 9.3.0 on Linux/x86_64) as bootstrap compiler. Rainer
Hi Rainer, > > The one experiment I'd like to be able to try, to investigate the > > cause/cure of this, is: > > > > diff --git a/gcc/calls.cc b/gcc/calls.cc index a4336c1..05fdd24 100644 > > --- a/gcc/calls.cc > > +++ b/gcc/calls.cc > > @@ -2177,7 +2177,7 @@ load_register_parameters (struct arg_data *args, > > int num_a > > VAR_DECL with a simple constructor, expand that constructor > > via a pseudo rather than read from (possibly misaligned) > > memory. PR middle-end/95126. */ > > - else if (nregs == 1 > > + else if (0 && nregs == 1 > > && partial == 0 > > && !args[i].pass_on_stack > > && VAR_P (tree_value) > > > > My "small const structs" patch affected code generation in three > > places, and identifying which of these is causing the miscompilation > > issue for gnat will help narrow down the problem, or worst case allow > > reverting less of the problematic patch. > > I just tried this on i386-pc-solaris2.11: unfortunately, it made no difference. Awesome! Very many thanks for trying this. Alas it confirms that the patch I'm currently spinning won't have any affect. So by a process of elimination, the miscompilation must be triggered by one of the other two changes: diff --git a/gcc/expr.cc b/gcc/expr.cc index fb062dc..37f1405 100644 --- a/gcc/expr.cc +++ b/gcc/expr.cc @@ -4871,7 +4871,7 @@ emit_push_insn (rtx x, machine_mode mode, tree type, rtx s /* If source is a constant VAR_DECL with a simple constructor, store the constructor to the stack instead of moving it. */ const_tree decl; - if (partial == 0 + if (0 && partial == 0 && MEM_P (xinner) && SYMBOL_REF_P (XEXP (xinner, 0)) && (decl = SYMBOL_REF_DECL (XEXP (xinner, 0))) != NULL_TREE @@ -10603,7 +10603,7 @@ expand_expr_real_1 (tree exp, rtx target, machine_mode t } /* Expand const VAR_DECLs with CONSTRUCTOR initializers that have scalar integer modes to a reg via store_constructor. */ - if (TREE_READONLY (exp) + if (0 && TREE_READONLY (exp) && !TREE_SIDE_EFFECTS (exp) && (modifier == EXPAND_NORMAL || modifier == EXPAND_STACK_PARM) && immediate_const_ctor_p (DECL_INITIAL (exp)) p.s. I've just set up a build environment on another machine where I'm using GNAT 11.3.1 20220421 (Red Hat 11.3.1-2) as the bootstrap compiler, but it'll be a few hours before I'm investigating in gdb. Many thanks again for your help. Sorry again for the breakage/inconvenience. Roger ==
Hi Roger, >> I just tried this on i386-pc-solaris2.11: unfortunately, it made no > difference. > > Awesome! Very many thanks for trying this. Alas it confirms that the patch > I'm currently spinning won't have any affect. So by a process of > elimination, > the miscompilation must be triggered by one of the other two changes: > > diff --git a/gcc/expr.cc b/gcc/expr.cc > index fb062dc..37f1405 100644 > --- a/gcc/expr.cc > +++ b/gcc/expr.cc > @@ -4871,7 +4871,7 @@ emit_push_insn (rtx x, machine_mode mode, tree type, > rtx s > /* If source is a constant VAR_DECL with a simple constructor, > store the constructor to the stack instead of moving it. */ > const_tree decl; > - if (partial == 0 > + if (0 && partial == 0 > && MEM_P (xinner) > && SYMBOL_REF_P (XEXP (xinner, 0)) > && (decl = SYMBOL_REF_DECL (XEXP (xinner, 0))) != NULL_TREE > @@ -10603,7 +10603,7 @@ expand_expr_real_1 (tree exp, rtx target, > machine_mode t > } > /* Expand const VAR_DECLs with CONSTRUCTOR initializers that > have scalar integer modes to a reg via store_constructor. */ > - if (TREE_READONLY (exp) > + if (0 && TREE_READONLY (exp) > && !TREE_SIDE_EFFECTS (exp) > && (modifier == EXPAND_NORMAL || modifier == EXPAND_STACK_PARM) > && immediate_const_ctor_p (DECL_INITIAL (exp)) I've tried both chunks individually: the second one allowed the build to finish successfully. Thanks. Rainer
diff --git a/gcc/calls.cc b/gcc/calls.cc index bbaf69c..a4336c1 100644 --- a/gcc/calls.cc +++ b/gcc/calls.cc @@ -2095,7 +2095,8 @@ load_register_parameters (struct arg_data *args, int num_actuals, poly_int64 size = 0; HOST_WIDE_INT const_size = 0; rtx_insn *before_arg = get_last_insn (); - tree type = TREE_TYPE (args[i].tree_value); + tree tree_value = args[i].tree_value; + tree type = TREE_TYPE (tree_value); if (RECORD_OR_UNION_TYPE_P (type) && TYPE_TRANSPARENT_AGGR (type)) type = TREE_TYPE (first_field (type)); /* Set non-negative if we must move a word at a time, even if @@ -2172,6 +2173,24 @@ load_register_parameters (struct arg_data *args, int num_actuals, emit_move_insn (gen_rtx_REG (word_mode, REGNO (reg) + j), args[i].aligned_regs[j]); + /* If we need a single register and the source is a constant + VAR_DECL with a simple constructor, expand that constructor + via a pseudo rather than read from (possibly misaligned) + memory. PR middle-end/95126. */ + else if (nregs == 1 + && partial == 0 + && !args[i].pass_on_stack + && VAR_P (tree_value) + && TREE_READONLY (tree_value) + && !TREE_SIDE_EFFECTS (tree_value) + && immediate_const_ctor_p (DECL_INITIAL (tree_value))) + { + rtx target = gen_reg_rtx (word_mode); + rtx x = expand_expr (DECL_INITIAL (tree_value), + target, word_mode, EXPAND_NORMAL); + reg = gen_rtx_REG (word_mode, REGNO (reg)); + emit_move_insn (reg, x); + } else if (partial == 0 || args[i].pass_on_stack) { /* SIZE and CONST_SIZE are 0 for partial arguments and diff --git a/gcc/expr.cc b/gcc/expr.cc index 1806091..26f5528 100644 --- a/gcc/expr.cc +++ b/gcc/expr.cc @@ -100,7 +100,7 @@ static void do_tablejump (rtx, machine_mode, rtx, rtx, rtx, profile_probability); static rtx const_vector_from_tree (tree); static tree tree_expr_size (const_tree); -static HOST_WIDE_INT int_expr_size (tree); +static HOST_WIDE_INT int_expr_size (const_tree); static void convert_mode_scalar (rtx, rtx, int); @@ -4867,7 +4867,22 @@ emit_push_insn (rtx x, machine_mode mode, tree type, rtx size, return false; } } - emit_block_move (target, xinner, size, BLOCK_OP_CALL_PARM); + + /* If source is a constant VAR_DECL with a simple constructor, + store the constructor to the stack instead of moving it. */ + const_tree decl; + if (partial == 0 + && MEM_P (xinner) + && SYMBOL_REF_P (XEXP (xinner, 0)) + && (decl = SYMBOL_REF_DECL (XEXP (xinner, 0))) != NULL_TREE + && VAR_P (decl) + && TREE_READONLY (decl) + && !TREE_SIDE_EFFECTS (decl) + && immediate_const_ctor_p (DECL_INITIAL (decl), 2)) + store_constructor (DECL_INITIAL (decl), target, 0, + int_expr_size (DECL_INITIAL (decl)), false); + else + emit_block_move (target, xinner, size, BLOCK_OP_CALL_PARM); } } else if (partial > 0) @@ -6576,6 +6591,25 @@ categorize_ctor_elements (const_tree ctor, HOST_WIDE_INT *p_nz_elts, p_init_elts, p_complete); } +/* Return true if constructor CTOR is simple enough to be materialized + in an integer mode register. Limit the size to WORDS words, which + is 1 by default. */ + +bool +immediate_const_ctor_p (const_tree ctor, unsigned int words) +{ + /* Allow function to be called with a VAR_DECL's DECL_INITIAL. */ + if (!ctor || TREE_CODE (ctor) != CONSTRUCTOR) + return false; + + return TREE_CONSTANT (ctor) + && !TREE_ADDRESSABLE (ctor) + && CONSTRUCTOR_NELTS (ctor) + && TREE_CODE (TREE_TYPE (ctor)) != ARRAY_TYPE + && int_expr_size (ctor) <= words * UNITS_PER_WORD + && initializer_constant_valid_for_bitfield_p (ctor); +} + /* TYPE is initialized by a constructor with NUM_ELTS elements, the last of which had type LAST_TYPE. Each element was itself a complete initializer, in the sense that every meaningful byte was explicitly @@ -10535,6 +10569,21 @@ expand_expr_real_1 (tree exp, rtx target, machine_mode tmode, if (temp) return temp; } + /* Expand const VAR_DECLs with CONSTRUCTOR initializers that + have scalar integer modes to a reg via store_constructor. */ + if (TREE_READONLY (exp) + && !TREE_SIDE_EFFECTS (exp) + && (modifier == EXPAND_NORMAL || modifier == EXPAND_STACK_PARM) + && immediate_const_ctor_p (DECL_INITIAL (exp)) + && SCALAR_INT_MODE_P (TYPE_MODE (TREE_TYPE (exp))) + && crtl->emit.regno_pointer_align_length + && !target) + { + target = gen_reg_rtx (TYPE_MODE (TREE_TYPE (exp))); + store_constructor (DECL_INITIAL (exp), target, 0, + int_expr_size (DECL_INITIAL (exp)), false); + return target; + } /* ... fall through ... */ case PARM_DECL: @@ -13129,7 +13178,7 @@ expr_size (tree exp) if the size can vary or is larger than an integer. */ static HOST_WIDE_INT -int_expr_size (tree exp) +int_expr_size (const_tree exp) { tree size; diff --git a/gcc/expr.h b/gcc/expr.h index 7e5cf49..d777c28 100644 --- a/gcc/expr.h +++ b/gcc/expr.h @@ -338,6 +338,7 @@ extern unsigned HOST_WIDE_INT highest_pow2_factor (const_tree); extern bool categorize_ctor_elements (const_tree, HOST_WIDE_INT *, HOST_WIDE_INT *, HOST_WIDE_INT *, bool *); +extern bool immediate_const_ctor_p (const_tree, unsigned int words = 1); extern void expand_operands (tree, tree, rtx, rtx*, rtx*, enum expand_modifier); diff --git a/gcc/varasm.cc b/gcc/varasm.cc index 6454f1c..826a9ca 100644 --- a/gcc/varasm.cc +++ b/gcc/varasm.cc @@ -5069,7 +5069,7 @@ initializer_constant_valid_p (tree value, tree endtype, bool reverse) an element of a "constant" initializer. */ bool -initializer_constant_valid_for_bitfield_p (tree value) +initializer_constant_valid_for_bitfield_p (const_tree value) { /* For bitfields we support integer constants or possibly nested aggregates of such. */ @@ -5078,7 +5078,7 @@ initializer_constant_valid_for_bitfield_p (tree value) case CONSTRUCTOR: { unsigned HOST_WIDE_INT idx; - tree elt; + const_tree elt; FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (value), idx, elt) if (!initializer_constant_valid_for_bitfield_p (elt)) diff --git a/gcc/varasm.h b/gcc/varasm.h index 8ba8374..acbd9fa 100644 --- a/gcc/varasm.h +++ b/gcc/varasm.h @@ -65,7 +65,7 @@ extern tree initializer_constant_valid_p (tree, tree, bool = false); /* Return true if VALUE is a valid constant-valued expression for use in initializing a static bit-field; one that can be an element of a "constant" initializer. */ -extern bool initializer_constant_valid_for_bitfield_p (tree); +extern bool initializer_constant_valid_for_bitfield_p (const_tree); /* Whether a constructor CTOR is a valid static constant initializer if all its elements are. This used to be internal to initializer_constant_valid_p diff --git a/gcc/testsuite/gcc.target/i386/pr95126-m32-1.c b/gcc/testsuite/gcc.target/i386/pr95126-m32-1.c new file mode 100644 index 0000000..1d6acd6 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr95126-m32-1.c @@ -0,0 +1,16 @@ +/* { dg-do compile { target { ia32 } } } */ +/* { dg-options "-O2" } */ + +struct small{ short a,b; signed char c; }; + +void call_func(void) +{ + extern int func(struct small X); + static struct small const s = { 1,2,0 }; + func(s); +} + +/* { dg-final { scan-assembler "movl\[ \\t]*\\\$" } } */ +/* { dg-final { scan-assembler "movb\[ \\t]*\\\$0, " } } */ +/* { dg-final { scan-assembler-not "movzwl" } } */ + diff --git a/gcc/testsuite/gcc.target/i386/pr95126-m32-2.c b/gcc/testsuite/gcc.target/i386/pr95126-m32-2.c new file mode 100644 index 0000000..b46be9d --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr95126-m32-2.c @@ -0,0 +1,16 @@ +/* { dg-do compile { target { ia32 } } } */ +/* { dg-options "-O2" } */ + +struct small{ short a,b; signed char c; }; +static const struct small s = { 1,2,0 }; +extern int func(struct small X); + +void call_func(void) +{ + func(s); +} + +/* { dg-final { scan-assembler "movl\[ \\t]*\\\$" } } */ +/* { dg-final { scan-assembler "movb\[ \\t]*\\\$0, " } } */ +/* { dg-final { scan-assembler-not "movzwl" } } */ + diff --git a/gcc/testsuite/gcc.target/i386/pr95126-m32-3.c b/gcc/testsuite/gcc.target/i386/pr95126-m32-3.c new file mode 100644 index 0000000..cc2fe94 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr95126-m32-3.c @@ -0,0 +1,15 @@ +/* { dg-do compile { target { ia32 } } } */ +/* { dg-options "-O2" } */ + +struct small{ short a; }; + +void call_func(void) +{ + extern int func(struct small X); + static struct small const s = { 2 }; + func(s); +} + +/* { dg-final { scan-assembler "pushl\[ \\t]*\\\$2" } } */ +/* { dg-final { scan-assembler-not "movzwl" } } */ + diff --git a/gcc/testsuite/gcc.target/i386/pr95126-m32-4.c b/gcc/testsuite/gcc.target/i386/pr95126-m32-4.c new file mode 100644 index 0000000..e829335 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr95126-m32-4.c @@ -0,0 +1,13 @@ +/* { dg-do compile { target { ia32 } } } */ +/* { dg-options "-O2" } */ + +struct small{ short a,b; }; + +void call_func(void) +{ + extern int func(struct small X); + static struct small const s = { 1,2 }; + func(s); +} + +/* { dg-final { scan-assembler "pushl\[ \\t]*\\\$131073" } } */ diff --git a/gcc/testsuite/gcc.target/i386/pr95126-m64-1.c b/gcc/testsuite/gcc.target/i386/pr95126-m64-1.c new file mode 100644 index 0000000..d5c6dded --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr95126-m64-1.c @@ -0,0 +1,17 @@ +/* { dg-do compile { target { ! ia32 } } } */ +/* { dg-options "-O2" } */ + +struct small{ short a,b; signed char c; }; + +void call_func(void) +{ + extern int func(struct small X); + static struct small const s = { 1,2,0 }; + func(s); +} + +/* { dg-final { scan-assembler "movl\[ \\t]*\\\$131073, " } } */ +/* { dg-final { scan-assembler-not "movzwl" } } */ +/* { dg-final { scan-assembler-not "salq" } } */ +/* { dg-final { scan-assembler-not "orq" } } */ + diff --git a/gcc/testsuite/gcc.target/i386/pr95126-m64-2.c b/gcc/testsuite/gcc.target/i386/pr95126-m64-2.c new file mode 100644 index 0000000..0230ffc --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr95126-m64-2.c @@ -0,0 +1,17 @@ +/* { dg-do compile { target { ! ia32 } } } */ +/* { dg-options "-O2" } */ + +struct small{ short a,b; signed char c; }; +static const struct small s = { 1,2,0 }; +extern int func(struct small X); + +void call_func(void) +{ + func(s); +} + +/* { dg-final { scan-assembler "movl\[ \\t]*\\\$131073, " } } */ +/* { dg-final { scan-assembler-not "movzwl" } } */ +/* { dg-final { scan-assembler-not "salq" } } */ +/* { dg-final { scan-assembler-not "orq" } } */ + diff --git a/gcc/testsuite/gcc.target/i386/pr95126-m64-3.c b/gcc/testsuite/gcc.target/i386/pr95126-m64-3.c new file mode 100644 index 0000000..25afe3a --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr95126-m64-3.c @@ -0,0 +1,14 @@ +/* { dg-do compile { target { ! ia32 } } } */ +/* { dg-options "-O2" } */ + +struct small{ short a; }; + +void call_func(void) +{ + extern int func(struct small X); + static struct small const s = { 2 }; + func(s); +} + +/* { dg-final { scan-assembler "movl\[ \\t]*\\\$2, " } } */ +/* { dg-final { scan-assembler-not "movzwl" } } */ diff --git a/gcc/testsuite/gcc.target/i386/pr95126-m64-4.c b/gcc/testsuite/gcc.target/i386/pr95126-m64-4.c new file mode 100644 index 0000000..71c7908 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr95126-m64-4.c @@ -0,0 +1,13 @@ +/* { dg-do compile { target { ! ia32 } } } */ +/* { dg-options "-O2" } */ + +struct small{ short a,b; }; + +void call_func(void) +{ + extern int func(struct small X); + static struct small const s = { 1,2 }; + func(s); +} + +/* { dg-final { scan-assembler "movl\[ \\t]*\\\$131073, " } } */