Bug 247256 - gcc segfaults (reproducable) on ppc
Summary: gcc segfaults (reproducable) on ppc
Alias: None
Product: Fedora
Classification: Fedora
Component: gcc   
(Show other bugs)
Version: rawhide
Hardware: All
OS: Linux
Target Milestone: ---
Assignee: Jakub Jelinek
QA Contact: Fedora Extras Quality Assurance
URL: http://koji.fedoraproject.org/koji/ge...
: 247509 (view as bug list)
Depends On:
Blocks: 247586
TreeView+ depends on / blocked
Reported: 2007-07-06 12:21 UTC by Hans de Goede
Modified: 2007-11-30 22:12 UTC (History)
2 users (show)

Fixed In Version:
Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of:
Last Closed: 2007-08-03 19:25:15 UTC
Type: ---
Regression: ---
Mount Type: ---
Documentation: ---
Verified Versions:
Category: ---
oVirt Team: ---
RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: ---

Attachments (Terms of Use)

Description Hans de Goede 2007-07-06 12:21:05 UTC
When trying to build a new release of allegro, I got a gcc segfault on the ppc
buildsys. At first I thought it was probably a hardware glitch, but requeueing
the build resulted in a segfault compiling the same file, and at the same line.


Since I do not have access to a ppc machine I cannot help with things like a
preprocessed C-file, etc. Sorry about that.

I did a yum update gcc on my i386 devel machine, and I cannot reproduce this there.

Comment 1 Jakub Jelinek 2007-07-09 15:26:28 UTC
This is a regression caused by the power6 indexed load/store tuning changes.

/* { dg-do compile } */
/* { dg-options "-O2 -ffast-math" } */

extern float sqrtf (float);

foo (const float *m)
  float x = m[0] + m[1] + m[2] + 1.0f;
  float s;

  if (x > 0.001)
    s = 0.5f / sqrtf (x);
    s = 2.0f * sqrtf (1.0f + m[0] - m[1] - m[2]);
  return s;

(reg:SF 121) m[2]
(reg:SF 127) m[0]
(reg:SF 123) m[1]
(reg:SF 126) 1.0f

We get an infinite recursion, backtrace (s_a_o is always alternating):
simplify_associative_operation (code=PLUS, mode=SFmode, op0=0x40003c7c3e0,
(gdb) p debug_rtx (op0)
(plus:SF (plus:SF (reg:SF 121 [ D.1301 ])
        (reg:SF 127))
    (reg:SF 123 [ D.1298 ]))
(gdb) p debug_rtx (op1)
(reg:SF 126)
simplify_binary_operation_1 (code=PLUS, mode=SFmode, op0=0x40003c7c3e0,
op1=0x40003c79920, trueop0=0x40003c7c3e0, trueop1=0x40003c79920)
simplify_binary_operation (code=PLUS, mode=SFmode, op0=0x40003c7c3e0,
simplify_gen_binary (code=PLUS, mode=SFmode, op0=0x40003c7c3e0,
simplify_associative_operation (code=PLUS, mode=SFmode, op0=0x40003c7c380,
(gdb) p debug_rtx (op0)
(plus:SF (plus:SF (reg:SF 121 [ D.1301 ])
        (reg:SF 127))
    (reg:SF 126))
(gdb) p debug_rtx (op1)
(reg:SF 123 [ D.1298 ])
simplify_binary_operation_1 (code=PLUS, mode=SFmode, op0=0x40003c7c380,
op1=0x40003c79720, trueop0=0x40003c7c380, trueop1=0x40003c79720)
simplify_binary_operation (code=PLUS, mode=SFmode, op0=0x40003c7c380,
simplify_gen_binary (code=PLUS, mode=SFmode, op0=0x40003c7c380,
simplify_associative_operation (code=PLUS, mode=SFmode, op0=0x40003c7c320,
(gdb) p debug_rtx (op0)
(plus:SF (plus:SF (reg:SF 121 [ D.1301 ])
        (reg:SF 127))
    (reg:SF 123 [ D.1298 ]))
(gdb) p debug_rtx (op1)
(reg:SF 126)

Comment 2 Jakub Jelinek 2007-07-09 21:02:48 UTC
I believe the cause is the newly introduced inconsistency between
swap_commutative_operands_p and simplify_plus_minus_op_data_cmp, in some
cases as on this testcase they go against each other.
swap_commutative_operands_p on power6 will prefer to put lower numbered pseudos
out of two pseudos first, while simplify_plus_minus will prefer in the same case
operand that used to come first before (that's what it uses ix member for).

The following patch cures this bug for me:

2007-07-09  Jakub Jelinek  <jakub@redhat.com>

        * simplify-rtx.c (simplify_plus_minus_op_data_cmp): If both operands
        are REGs and TARGET_INDEX_OPERAND_FIRST, sort lower REGNOs first.

--- gcc/simplify-rtx.c.jj   2006-08-11 17:32:05.000000000 +0200
+++ gcc/simplify-rtx.c      2007-07-09 22:53:26.000000000 +0200
@@ -2608,6 +2608,12 @@ simplify_plus_minus_op_data_cmp (const v
            - commutative_operand_precedence (d1->op));
   if (result)
     return result;
+  /* Group together equal REGs to do more simplification.  */
+  if (TARGET_INDEX_OPERAND_FIRST && REG_P (d1->op) && REG_P (d2->op)
+      && REGNO (d1->op) != REGNO (d2->op))
+    return REGNO (d1->op) - REGNO (d2->op);
   return d1->ix - d2->ix;

but I haven't done any testing on it other than the testcase.
For Peter's upstream PR28690 patch this would mean removing
"TARGET_INDEX_OPERAND_FIRST && " from the patch, as it does this ordering

Comment 3 Peter Bergner 2007-07-09 21:39:20 UTC
I'll bootstrap and regtest this on powerpc64-linux using the
redhat/gcc-4_1-branch and report back.

Comment 4 Jakub Jelinek 2007-07-10 11:03:22 UTC
*** Bug 247509 has been marked as a duplicate of this bug. ***

Comment 5 Peter Bergner 2007-07-10 16:41:10 UTC
Jakub's patch from Comment #2 applied to the redhat/gcc-4_1-branch bootstrapped
and regtested (running the testsuite using both -m32 and -m64) on
powerpc64-linux with no regressions.  This patch looks good to me.

Comment 6 Hans de Goede 2007-07-24 19:10:15 UTC
I can confirm that, with gcc-4.1.2-16, allegro builds on rawhide again now. I
cannot verify if it actually works though, but the segfault is resolved so I
think this bug can be closed.

Note You need to log in before you can comment on or make changes to this bug.