Bug 247586

Summary: gcc segfaults (reproducable) on ppc
Product: Red Hat Enterprise Linux 5 Reporter: Jakub Jelinek <jakub>
Component: gccAssignee: Jakub Jelinek <jakub>
Status: CLOSED ERRATA QA Contact:
Severity: high Docs Contact:
Priority: medium    
Version: 5.0CC: bergner
Target Milestone: ---Keywords: Regression
Target Release: ---   
Hardware: powerpc   
OS: Linux   
URL: http://koji.fedoraproject.org/koji/getfile?taskID=58008&name=build.log
Whiteboard:
Fixed In Version: RHBA-2007-0616 Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of: Environment:
Last Closed: 2007-11-07 20:09:33 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: 247256    
Bug Blocks:    

Description Jakub Jelinek 2007-07-10 07:35:16 UTC
+++ This bug was initially created as a clone of Bug #247256 +++

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.

-- Additional comment from jakub on 2007-07-09 11:26 EST --
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)
...


-- Additional comment from jakub on 2007-07-09 17:02 EST --
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.

-- Additional comment from bergner.com on 2007-07-09 17:39 EST --
I'll bootstrap and regtest this on powerpc64-linux using the
redhat/gcc-4_1-branch and report back.

Comment 12 errata-xmlrpc 2007-11-07 20:09:33 UTC
An advisory has been issued which should help the problem
described in this bug report. This report is therefore being
closed with a resolution of ERRATA. For more information
on the solution and/or where to find the updated files,
please follow the link below. You may reopen this bug report
if the solution does not work for you.

http://rhn.redhat.com/errata/RHBA-2007-0616.html