Bug 59863 - const array in function is placed on stack
Summary: const array in function is placed on stack
Status: NEW
Alias: None
Product: gcc
Classification: Unclassified
Component: middle-end (show other bugs)
Version: 4.8.2
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords: missed-optimization
: 93102 94010 99091 114342 (view as bug list)
Depends on:
Blocks:
 
Reported: 2014-01-17 18:50 UTC by Samuel Tardieu
Modified: 2024-03-19 18:14 UTC (History)
8 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2021-09-25 00:00:00


Attachments
Source file to reproduce the issue (83 bytes, text/plain)
2014-01-17 18:50 UTC, Samuel Tardieu
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Samuel Tardieu 2014-01-17 18:50:54 UTC
Created attachment 31875 [details]
Source file to reproduce the issue

This source code

int f(int i) {
  const int a[] = {1, 2, 3, 4};
  return a[i];
}

int g(int i) {
  static const int a[] = {1, 2, 3, 4};
  return a[i];
}

generates different code with GCC 4.8.2 on x86_64 for f() and g(). In f(), the const array is really created on the stack, and initialized one element at a time, instead of being placed in .rodata as it is for g().

With GCC on ARM (4.7), both arrays from f() and g() are placed in .rodata, but the code to access them is different:

	.text
	.align	2
	.global	f
	.type	f, %function
f:
	@ args = 0, pretend = 0, frame = 16
	@ frame_needed = 0, uses_anonymous_args = 0
	@ link register save eliminated.
	str	r4, [sp, #-4]!
	ldr	r3, .L2
	sub	sp, sp, #20
	mov	ip, r0
	ldmia	r3, {r0, r1, r2, r3}
	add	r4, sp, #16
	stmdb	r4, {r0, r1, r2, r3}
	add	ip, r4, ip, asl #2
	ldr	r0, [ip, #-16]
	add	sp, sp, #20
	ldmfd	sp!, {r4}
	bx	lr
.L3:
	.align	2
.L2:
	.word	.LANCHOR0
	.size	f, .-f
	.align	2
	.global	g
	.type	g, %function
g:
	@ args = 0, pretend = 0, frame = 0
	@ frame_needed = 0, uses_anonymous_args = 0
	@ link register save eliminated.
	ldr	r3, .L5
	add	r0, r3, r0, asl #2
	ldr	r0, [r0, #16]
	bx	lr
.L6:
	.align	2
.L5:
	.word	.LANCHOR0
	.size	g, .-g
	.section	.rodata
	.align	2
	.set	.LANCHOR0,. + 0
.LC0:
	.word	1
	.word	2
	.word	3
	.word	4
	.type	a.4057, %object
	.size	a.4057, 16
a.4057:
	.word	1
	.word	2
	.word	3
	.word	4

Note that on x86_64, clang generates the same code for f() and g() and even unifies both const arrays in .rodata.

Is there anything in the C standard preventing a const array declared in a function from being put in .rodata or are those missed optimizations?
Comment 1 jsm-csl@polyomino.org.uk 2014-01-17 23:26:04 UTC
On Fri, 17 Jan 2014, sam at gcc dot gnu.org wrote:

> Is there anything in the C standard preventing a const array declared in a
> function from being put in .rodata or are those missed optimizations?

If the object address can escape and the function can be called 
recursively, this would violate the requirement for distinct objects to 
have distinct addresses.  (See discussion on comp.std.c, "uniqueness of 
automatic objects", Nov 2008; I'm not sure if there was a corresponding 
GCC bug report / fix.)
Comment 2 Andrew Pinski 2014-01-17 23:30:57 UTC
This is caused by checking TREE_ADDRESSABLE on the a decl which is correct thing to do but the issue is there is no addressing taking in the code (only an implicit one with a[i]:
      /* An array that is indexed by a non-constant
	 cannot be stored in a register; we must be able to do
	 address arithmetic on its address.
	 Likewise an array of elements of variable size.  */
Comment 3 Richard Biener 2014-01-20 09:15:15 UTC
This is also simply a gimplification issue.  For larger arrays we initialize
the stack with an aggregate copy from the constant pool.
Comment 4 Samuel Tardieu 2014-01-20 09:42:28 UTC
Note that clang has this bug "in reverse": it unifies the arrays even when recursive calls are possible and address escapes the defining function (http://llvm.org/bugs/show_bug.cgi?id=18557).
Comment 5 Richard Biener 2020-03-04 07:37:26 UTC
*** Bug 94010 has been marked as a duplicate of this bug. ***
Comment 6 Andrew Pinski 2021-09-25 01:34:27 UTC
*** Bug 93102 has been marked as a duplicate of this bug. ***
Comment 7 Andrew Pinski 2021-09-25 01:39:06 UTC
Confirmed.
Comment 8 Andrew Pinski 2024-03-15 00:07:12 UTC
*** Bug 99091 has been marked as a duplicate of this bug. ***
Comment 9 AK 2024-03-19 17:26:20 UTC
*** Bug 114342 has been marked as a duplicate of this bug. ***
Comment 10 Xi Ruoyao 2024-03-19 18:14:30 UTC
Note that if we take a pointer to such an array this optimization will be invalid.  And unfortunately the mis-optimization is already happening (even for non-const arrays) with some strange command line switch combinations.  See PR114206.