Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
* [PATCH] Prevent GCC from folding inline test functions
@ 2015-08-21 13:05 Luis Machado
  2015-08-21 16:03 ` Pedro Alves
  0 siblings, 1 reply; 7+ messages in thread
From: Luis Machado @ 2015-08-21 13:05 UTC (permalink / raw)
  To: gdb-patches

While doing some powerpc Linux tests on a ppc 476 board using GCC 5.2, i
noticed inline-bt.exp, inline-cmds.exp and inline-locals.exp failing.

FAIL: gdb.opt/inline-bt.exp: continue to bar (1)
FAIL: gdb.opt/inline-bt.exp: backtrace from bar (1)
FAIL: gdb.opt/inline-bt.exp: continue to bar (2)
FAIL: gdb.opt/inline-bt.exp: backtrace from bar (2)
FAIL: gdb.opt/inline-bt.exp: continue to bar (3)
FAIL: gdb.opt/inline-bt.exp: backtrace from bar (3)
FAIL: gdb.opt/inline-cmds.exp: continue to bar (1)
FAIL: gdb.opt/inline-cmds.exp: backtrace from bar (1)
FAIL: gdb.opt/inline-cmds.exp: continue to bar (2)
FAIL: gdb.opt/inline-cmds.exp: backtrace from bar (2)
FAIL: gdb.opt/inline-cmds.exp: continue to marker
FAIL: gdb.opt/inline-cmds.exp: backtrace from marker
FAIL: gdb.opt/inline-cmds.exp: step into finish marker
FAIL: gdb.opt/inline-locals.exp: continue to bar (1)
FAIL: gdb.opt/inline-locals.exp: continue to bar (2)
FAIL: gdb.opt/inline-locals.exp: backtrace from bar (2)
FAIL: gdb.opt/inline-locals.exp: continue to bar (3)
FAIL: gdb.opt/inline-locals.exp: backtrace from bar (3)

They failed because the breakpoint supposedly inserted at bar was actually
inserted at noinline.

(gdb) break inline-markers.c:20^M
Breakpoint 2 at 0x1000079c: file gdb/testsuite/gdb.opt/inline-markers.c, line 20.^M
(gdb) continue^M
Continuing.^M
^M
Breakpoint 2, noinline () at gdb/testsuite/gdb.opt/inline-markers.c:35^M
35        inlined_fn (); /* inlined */^M

As we can see, line 20 is really inside bar, not noinline:

18 void bar(void)
19 {
20   x += y; /* set breakpoint 1 here */
21 }

Further investigation shows that this is really due to GCC 5's new
ICF pass (-fipa-icf), now enabled by default at -O2, which folds bar
and marker into noinline, where the call to inlined_fn was inlined.

This breaks the testcase since it expects to stop at specific spots.

I thought about two possible fixes for this issue.

- Disable the ICF pass manually when building the binary (-fno-ipa-icf).

This has the advantage of not having to touch the testcase sources themselves,
but the disadvantage of having to add conditional blocks to test the GCC
version. If we ever change GCC's default, we will have to adjust the
conditional block again to match GCC's behavior.

- Modify the testcase sources to make the identical functions unique.

This solution doesn't touch the testcase itself, but changes the source
code slightly in order to make bar, marker and inlined_fn unique. This
causes GCC's ICF pass to ignore these functions and not fold them into
a common identical function.

I'm good with either of them, but i'm more inclined to go with the second
one.

The attached patch implements this by adding the new global variable z, set
to 0, that gets added in different ways to marker and inlined_fn. Since it
is 0, it doesn't affect any possible value checks that we may wish to do
in the future (we currently only check for values changed by bar).

Ok?

ps: I also noticed GDB doesn't do a great job at stating that the breakpoint
was actually inserted at a different source line than previously requested,
so this sounds like a bug that should be fixed, if it is not just wrong
DWARF information (did not investigate it further).

gdb/testsuite/ChangeLog:

	* gdb.opt/inline-bt.c: New global z.
	* gdb.opt/inline-cmds.c: Likewise.
	* gdb.opt/inline-locals.c: Likewise.
	* gdb.opt/inline-markers.c: New extern global z.
	(marker): Use z.
	(inline_fn): Likewise.
---
 gdb/testsuite/gdb.opt/inline-bt.c      | 1 +
 gdb/testsuite/gdb.opt/inline-cmds.c    | 1 +
 gdb/testsuite/gdb.opt/inline-locals.c  | 1 +
 gdb/testsuite/gdb.opt/inline-markers.c | 6 +++---
 4 files changed, 6 insertions(+), 3 deletions(-)

diff --git a/gdb/testsuite/gdb.opt/inline-bt.c b/gdb/testsuite/gdb.opt/inline-bt.c
index dc2bd45..baa6fd4 100644
--- a/gdb/testsuite/gdb.opt/inline-bt.c
+++ b/gdb/testsuite/gdb.opt/inline-bt.c
@@ -23,6 +23,7 @@
 #endif
 
 int x, y;
+int z = 0;
 volatile int result;
 
 void bar(void);
diff --git a/gdb/testsuite/gdb.opt/inline-cmds.c b/gdb/testsuite/gdb.opt/inline-cmds.c
index 9955720..2569289 100644
--- a/gdb/testsuite/gdb.opt/inline-cmds.c
+++ b/gdb/testsuite/gdb.opt/inline-cmds.c
@@ -23,6 +23,7 @@
 #endif
 
 int x, y;
+int z = 0;
 volatile int result;
 
 void bar(void);
diff --git a/gdb/testsuite/gdb.opt/inline-locals.c b/gdb/testsuite/gdb.opt/inline-locals.c
index fc018bf..143f7ff 100644
--- a/gdb/testsuite/gdb.opt/inline-locals.c
+++ b/gdb/testsuite/gdb.opt/inline-locals.c
@@ -23,6 +23,7 @@
 #endif
 
 int x, y;
+int z = 0;
 volatile int result;
 volatile int *array_p;
 
diff --git a/gdb/testsuite/gdb.opt/inline-markers.c b/gdb/testsuite/gdb.opt/inline-markers.c
index 46c68ae..5d55033 100644
--- a/gdb/testsuite/gdb.opt/inline-markers.c
+++ b/gdb/testsuite/gdb.opt/inline-markers.c
@@ -13,7 +13,7 @@
    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
-extern int x, y;
+extern int x, y, z;
 
 void bar(void)
 {
@@ -22,12 +22,12 @@ void bar(void)
 
 void marker(void)
 {
-  x += y; /* set breakpoint 2 here */
+  x += y - z; /* set breakpoint 2 here */
 }
 
 inline void inlined_fn(void)
 {
-  x += y;
+  x += y + z;
 }
 
 void noinline(void)
-- 
1.9.1


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH] Prevent GCC from folding inline test functions
  2015-08-21 13:05 [PATCH] Prevent GCC from folding inline test functions Luis Machado
@ 2015-08-21 16:03 ` Pedro Alves
  2015-08-24 15:49   ` Luis Machado
  0 siblings, 1 reply; 7+ messages in thread
From: Pedro Alves @ 2015-08-21 16:03 UTC (permalink / raw)
  To: Luis Machado, gdb-patches

On 08/21/2015 02:05 PM, Luis Machado wrote:

> The attached patch implements this by adding the new global variable z, set
> to 0, that gets added in different ways to marker and inlined_fn. Since it
> is 0, it doesn't affect any possible value checks that we may wish to do
> in the future (we currently only check for values changed by bar).
> 
> Ok?
> 

OK, though you should probably make z volatile as well.
Otherwise, soon enough, gcc with LTO sees that z is always 0:

> +int z = 0;

and then these compile down to the same again, and get folded:

> +  x += y - z;
> +  x += y + z;

Thanks,
Pedro Alves


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH] Prevent GCC from folding inline test functions
  2015-08-21 16:03 ` Pedro Alves
@ 2015-08-24 15:49   ` Luis Machado
  2015-08-24 15:54     ` Pedro Alves
  0 siblings, 1 reply; 7+ messages in thread
From: Luis Machado @ 2015-08-24 15:49 UTC (permalink / raw)
  To: Pedro Alves, gdb-patches

[-- Attachment #1: Type: text/plain, Size: 593 bytes --]

On 08/21/2015 01:03 PM, Pedro Alves wrote:
> On 08/21/2015 02:05 PM, Luis Machado wrote:
>
>> The attached patch implements this by adding the new global variable z, set
>> to 0, that gets added in different ways to marker and inlined_fn. Since it
>> is 0, it doesn't affect any possible value checks that we may wish to do
>> in the future (we currently only check for values changed by bar).
>>
>> Ok?
>>
>
> OK, though you should probably make z volatile as well.
> Otherwise, soon enough, gcc with LTO sees that z is always 0:
>

Indeed.

Attached is what i pushed to trunk.

Thanks,
Luis

[-- Attachment #2: inline.diff --]
[-- Type: text/x-patch, Size: 6180 bytes --]

commit a48847eea5f39c1f9fbe4255c9e892647f13f995
Author: Luis Machado <lgustavo@codesourcery.com>
Date:   Mon Aug 24 12:33:21 2015 -0300

    Prevent GCC from folding inline test functions
    
    While doing some powerpc Linux tests on a ppc 476 board using GCC 5.2, i
    noticed inline-bt.exp, inline-cmds.exp and inline-locals.exp failing.
    
    FAIL: gdb.opt/inline-bt.exp: continue to bar (1)
    FAIL: gdb.opt/inline-bt.exp: backtrace from bar (1)
    FAIL: gdb.opt/inline-bt.exp: continue to bar (2)
    FAIL: gdb.opt/inline-bt.exp: backtrace from bar (2)
    FAIL: gdb.opt/inline-bt.exp: continue to bar (3)
    FAIL: gdb.opt/inline-bt.exp: backtrace from bar (3)
    FAIL: gdb.opt/inline-cmds.exp: continue to bar (1)
    FAIL: gdb.opt/inline-cmds.exp: backtrace from bar (1)
    FAIL: gdb.opt/inline-cmds.exp: continue to bar (2)
    FAIL: gdb.opt/inline-cmds.exp: backtrace from bar (2)
    FAIL: gdb.opt/inline-cmds.exp: continue to marker
    FAIL: gdb.opt/inline-cmds.exp: backtrace from marker
    FAIL: gdb.opt/inline-cmds.exp: step into finish marker
    FAIL: gdb.opt/inline-locals.exp: continue to bar (1)
    FAIL: gdb.opt/inline-locals.exp: continue to bar (2)
    FAIL: gdb.opt/inline-locals.exp: backtrace from bar (2)
    FAIL: gdb.opt/inline-locals.exp: continue to bar (3)
    FAIL: gdb.opt/inline-locals.exp: backtrace from bar (3)
    
    They failed because the breakpoint supposedly inserted at bar was actually
    inserted at noinline.
    
    (gdb) break inline-markers.c:20^M
    Breakpoint 2 at 0x1000079c: file gdb/testsuite/gdb.opt/inline-markers.c, line 20.^M
    (gdb) continue^M
    Continuing.^M
    ^M
    Breakpoint 2, noinline () at gdb/testsuite/gdb.opt/inline-markers.c:35^M
    35        inlined_fn (); /* inlined */^M
    
    As we can see, line 20 is really inside bar, not noinline:
    
    18 void bar(void)
    19 {
    20   x += y; /* set breakpoint 1 here */
    21 }
    
    Further investigation shows that this is really due to GCC 5's new
    ICF pass (-fipa-icf), now enabled by default at -O2, which folds bar
    and marker into noinline, where the call to inlined_fn was inlined.
    
    This breaks the testcase since it expects to stop at specific spots.
    
    I thought about two possible fixes for this issue.
    
    - Disable the ICF pass manually when building the binary (-fno-ipa-icf).
    
    This has the advantage of not having to touch the testcase sources themselves,
    but the disadvantage of having to add conditional blocks to test the GCC
    version. If we ever change GCC's default, we will have to adjust the
    conditional block again to match GCC's behavior.
    
    - Modify the testcase sources to make the identical functions unique.
    
    This solution doesn't touch the testcase itself, but changes the source
    code slightly in order to make bar, marker and inlined_fn unique. This
    causes GCC's ICF pass to ignore these functions and not fold them into
    a common identical function.
    
    I'm good with either of them, but i'm more inclined to go with the second
    one.
    
    The attached patch implements this by adding the new global variable z, set
    to 0, that gets added in different ways to marker and inlined_fn. Since it
    is 0, it doesn't affect any possible value checks that we may wish to do
    in the future (we currently only check for values changed by bar).
    
    Ok?
    
    ps: I also noticed GDB doesn't do a great job at stating that the breakpoint
    was actually inserted at a different source line than previously requested,
    so this sounds like a bug that should be fixed, if it is not just wrong
    DWARF information (did not investigate it further).
    
    gdb/testsuite/ChangeLog:
    
    2015-08-24  Luis Machado  <lgustavo@codesourcery.com>
    
    	* gdb.opt/inline-bt.c: New volatile global z.
    	* gdb.opt/inline-cmds.c: Likewise.
    	* gdb.opt/inline-locals.c: Likewise.
    	* gdb.opt/inline-markers.c: New extern global z.
    	(marker): Use z.
    	(inline_fn): Likewise.

diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog
index c3d5182..b788c0f 100644
--- a/gdb/testsuite/ChangeLog
+++ b/gdb/testsuite/ChangeLog
@@ -1,3 +1,12 @@
+2015-08-24  Luis Machado  <lgustavo@codesourcery.com>
+
+	* gdb.opt/inline-bt.c: New volatile global z.
+	* gdb.opt/inline-cmds.c: Likewise.
+	* gdb.opt/inline-locals.c: Likewise.
+	* gdb.opt/inline-markers.c: New extern global z.
+	(marker): Use z.
+	(inline_fn): Likewise.
+
 2015-08-24  Pedro Alves  <palves@redhat.com>
 
 	* config/m32r-stub.exp: Remove file.
diff --git a/gdb/testsuite/gdb.opt/inline-bt.c b/gdb/testsuite/gdb.opt/inline-bt.c
index dc2bd45..a47d16e 100644
--- a/gdb/testsuite/gdb.opt/inline-bt.c
+++ b/gdb/testsuite/gdb.opt/inline-bt.c
@@ -23,6 +23,7 @@
 #endif
 
 int x, y;
+volatile int z = 0;
 volatile int result;
 
 void bar(void);
diff --git a/gdb/testsuite/gdb.opt/inline-cmds.c b/gdb/testsuite/gdb.opt/inline-cmds.c
index 9955720..cc43b57 100644
--- a/gdb/testsuite/gdb.opt/inline-cmds.c
+++ b/gdb/testsuite/gdb.opt/inline-cmds.c
@@ -23,6 +23,7 @@
 #endif
 
 int x, y;
+volatile int z = 0;
 volatile int result;
 
 void bar(void);
diff --git a/gdb/testsuite/gdb.opt/inline-locals.c b/gdb/testsuite/gdb.opt/inline-locals.c
index fc018bf..fa5cd13 100644
--- a/gdb/testsuite/gdb.opt/inline-locals.c
+++ b/gdb/testsuite/gdb.opt/inline-locals.c
@@ -23,6 +23,7 @@
 #endif
 
 int x, y;
+volatile int z = 0;
 volatile int result;
 volatile int *array_p;
 
diff --git a/gdb/testsuite/gdb.opt/inline-markers.c b/gdb/testsuite/gdb.opt/inline-markers.c
index 46c68ae..5d55033 100644
--- a/gdb/testsuite/gdb.opt/inline-markers.c
+++ b/gdb/testsuite/gdb.opt/inline-markers.c
@@ -13,7 +13,7 @@
    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
-extern int x, y;
+extern int x, y, z;
 
 void bar(void)
 {
@@ -22,12 +22,12 @@ void bar(void)
 
 void marker(void)
 {
-  x += y; /* set breakpoint 2 here */
+  x += y - z; /* set breakpoint 2 here */
 }
 
 inline void inlined_fn(void)
 {
-  x += y;
+  x += y + z;
 }
 
 void noinline(void)

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH] Prevent GCC from folding inline test functions
  2015-08-24 15:49   ` Luis Machado
@ 2015-08-24 15:54     ` Pedro Alves
  2015-08-24 15:59       ` Luis Machado
  0 siblings, 1 reply; 7+ messages in thread
From: Pedro Alves @ 2015-08-24 15:54 UTC (permalink / raw)
  To: Luis Machado, gdb-patches

On 08/24/2015 04:48 PM, Luis Machado wrote:
> --- a/gdb/testsuite/gdb.opt/inline-markers.c
> +++ b/gdb/testsuite/gdb.opt/inline-markers.c
> @@ -13,7 +13,7 @@
>     You should have received a copy of the GNU General Public License
>     along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
>  
> -extern int x, y;
> +extern int x, y, z;

z here should match the definition (should be volatile here too).

Thanks,
Pedro Alves


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH] Prevent GCC from folding inline test functions
  2015-08-24 15:54     ` Pedro Alves
@ 2015-08-24 15:59       ` Luis Machado
  2015-08-24 16:07         ` Pedro Alves
  0 siblings, 1 reply; 7+ messages in thread
From: Luis Machado @ 2015-08-24 15:59 UTC (permalink / raw)
  To: Pedro Alves, gdb-patches

On 08/24/2015 12:53 PM, Pedro Alves wrote:
> On 08/24/2015 04:48 PM, Luis Machado wrote:
>> --- a/gdb/testsuite/gdb.opt/inline-markers.c
>> +++ b/gdb/testsuite/gdb.opt/inline-markers.c
>> @@ -13,7 +13,7 @@
>>      You should have received a copy of the GNU General Public License
>>      along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
>>
>> -extern int x, y;
>> +extern int x, y, z;
>
> z here should match the definition (should be volatile here too).
>
> Thanks,
> Pedro Alves
>

Fixed with 91dddb86299bba404599551e9e2633b3c0e5c830.


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH] Prevent GCC from folding inline test functions
  2015-08-24 15:59       ` Luis Machado
@ 2015-08-24 16:07         ` Pedro Alves
  2015-08-24 16:11           ` Luis Machado
  0 siblings, 1 reply; 7+ messages in thread
From: Pedro Alves @ 2015-08-24 16:07 UTC (permalink / raw)
  To: Luis Machado, gdb-patches

On 08/24/2015 04:59 PM, Luis Machado wrote:
> On 08/24/2015 12:53 PM, Pedro Alves wrote:
>> On 08/24/2015 04:48 PM, Luis Machado wrote:
>>> --- a/gdb/testsuite/gdb.opt/inline-markers.c
>>> +++ b/gdb/testsuite/gdb.opt/inline-markers.c
>>> @@ -13,7 +13,7 @@
>>>      You should have received a copy of the GNU General Public License
>>>      along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
>>>
>>> -extern int x, y;
>>> +extern int x, y, z;
>>
>> z here should match the definition (should be volatile here too).
>>
>> Thanks,
>> Pedro Alves
>>
> 
> Fixed with 91dddb86299bba404599551e9e2633b3c0e5c830.
> 

Thanks.  Though,

 -extern int x, y, z;
 +extern int x, y;
 +extern volatile z;

I think this will cause trouble with newer gcc that default
to gnu c11.  Since C99 that a missing type specifier is no
longer implicitly assumed to be int.  Thus that should really be:

extern volatile int z;

Thanks,
Pedro Alves


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH] Prevent GCC from folding inline test functions
  2015-08-24 16:07         ` Pedro Alves
@ 2015-08-24 16:11           ` Luis Machado
  0 siblings, 0 replies; 7+ messages in thread
From: Luis Machado @ 2015-08-24 16:11 UTC (permalink / raw)
  To: Pedro Alves, gdb-patches

On 08/24/2015 01:07 PM, Pedro Alves wrote:
> On 08/24/2015 04:59 PM, Luis Machado wrote:
>> On 08/24/2015 12:53 PM, Pedro Alves wrote:
>>> On 08/24/2015 04:48 PM, Luis Machado wrote:
>>>> --- a/gdb/testsuite/gdb.opt/inline-markers.c
>>>> +++ b/gdb/testsuite/gdb.opt/inline-markers.c
>>>> @@ -13,7 +13,7 @@
>>>>       You should have received a copy of the GNU General Public License
>>>>       along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
>>>>
>>>> -extern int x, y;
>>>> +extern int x, y, z;
>>>
>>> z here should match the definition (should be volatile here too).
>>>
>>> Thanks,
>>> Pedro Alves
>>>
>>
>> Fixed with 91dddb86299bba404599551e9e2633b3c0e5c830.
>>
>
> Thanks.  Though,
>
>   -extern int x, y, z;
>   +extern int x, y;
>   +extern volatile z;
>
> I think this will cause trouble with newer gcc that default
> to gnu c11.  Since C99 that a missing type specifier is no
> longer implicitly assumed to be int.  Thus that should really be:
>
> extern volatile int z;
>
> Thanks,
> Pedro Alves
>

Fixed in 4422ac93e5d3d23dd441aadaa49c81356aa59b73.


^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2015-08-24 16:11 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-08-21 13:05 [PATCH] Prevent GCC from folding inline test functions Luis Machado
2015-08-21 16:03 ` Pedro Alves
2015-08-24 15:49   ` Luis Machado
2015-08-24 15:54     ` Pedro Alves
2015-08-24 15:59       ` Luis Machado
2015-08-24 16:07         ` Pedro Alves
2015-08-24 16:11           ` Luis Machado

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox