Bug 247256

Summary: gcc segfaults (reproducable) on ppc
Product: [Fedora] Fedora Reporter: Hans de Goede <hdegoede>
Component: gccAssignee: Jakub Jelinek <jakub>
Status: CLOSED RAWHIDE QA Contact: Fedora Extras Quality Assurance <extras-qa>
Severity: high Docs Contact:
Priority: medium    
Version: rawhideCC: ajax, bergner
Target Milestone: ---   
Target Release: ---   
Hardware: All   
OS: Linux   
URL: http://koji.fedoraproject.org/koji/getfile?taskID=58008&name=build.log
Whiteboard:
Fixed In Version: Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of: Environment:
Last Closed: 2007-08-03 19:25:15 UTC Type: ---
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Embargoed:
Bug Depends On:    
Bug Blocks: 247586    

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.

See:
http://koji.fedoraproject.org/koji/getfile?taskID=58008&name=build.log

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);

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);
  else
    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,
op1=0x40003c79920)
(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,
op1=0x40003c79920)
simplify_gen_binary (code=PLUS, mode=SFmode, op0=0x40003c7c3e0,
op1=0x40003c79920)
simplify_associative_operation (code=PLUS, mode=SFmode, op0=0x40003c7c380,
op1=0x40003c79720)
(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,
op1=0x40003c79720)
simplify_gen_binary (code=PLUS, mode=SFmode, op0=0x40003c7c380,
op1=0x40003c79720)
simplify_associative_operation (code=PLUS, mode=SFmode, op0=0x40003c7c320,
op1=0x40003c79920)
(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>

        * 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
unconditionally.

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.