http://gcc.gnu.org/bugzilla/show_bug.cgi?id=56894
Bug #: 56894 Summary: performance regression in gcc 4.7.x due to a += operation Classification: Unclassified Product: gcc Version: 4.7.3 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ AssignedTo: unassig...@gcc.gnu.org ReportedBy: laurent.alfo...@st.com Hello, I have identified a big performance regression between 4.6 and 4.7. (I have enclosed the pathological test). After investigation, it is because of the += statement applied on 2 signed chars. - It is now type-promoted to "int" when it is written "result += foo()". (since 4.7) - it is type promoted to "unsigned char" when it is written "result = result + foo()". The "char->int->char" cast is blocking the sccp constant propagation optimization. More precisely, in gcc 4.6, the "result" variable is seen as a loop_invariant (no_evolution_in_loop_p): <nop_expr 0xf7fbb8a4 type <integer_type 0xf7ee4180 char sizes-gimplified public string-flag type_6 QI [...]> arg 0 <polynomial_chrec 0xf7fb96e4 type <integer_type 0xf7ee4120 unsigned char public unsigned string-flag QI [...]> arg 0 <integer_cst 0xf7eccac0 constant 2> arg 1 <integer_cst 0xf7ecc120 constant 0> arg 2 <integer_cst 0xf7f88e20 constant 1>>> In gcc 4.7, the result variable is not seen as a loop_invariant due to the cast to int: type <integer_type 0xf7de32a0 char sizes-gimplified public string-flag type_6 QI[...]> arg 0 <polynomial_chrec 0xf7ecd180 type <integer_type 0xf7de33c0 int sizes-gimplified public type_6 SI[...]> arg 0 <integer_cst 0xf7dcbe70 constant 2> arg 1 <integer_cst 0xf7dcba80 constant 0> arg 2 <integer_cst 0xf7dcba9c constant 1>>> I don't know how to change the chrec detection to recover the constant propagation in gcc 4.7. Thanks, Laurent