User account creation filtered due to spam.
gcc 5, 6, 7 for 32-bit target all fail to compile the following testcase w/ -O1: long long int ro, t9; void cg (void) { ro = (t9 != 1); ro += (t9 != 0) ? t9 : ro; } % powerpc-e500v2-linux-gnuspe-gcc-5.4.0 -c -O1 fxgjkta3.c powerpc-e500v2-linux-gnuspe-gcc-5.4.0: internal compiler error: Segmentation fault (program cc1) % powerpc-e500v2-linux-gnuspe-gcc-7.0.0-alpha20160626 -c -O1 fxgjkta3.c powerpc-e500v2-linux-gnuspe-gcc-7.0.0-alpha20160626: internal compiler error: Segmentation fault (program cc1) Backtrace for gcc 7: #0 0x0000000000eb99a6 in simplify_binary_operation_1(rtx_code, machine_mode, rtx_def*, rtx_def*, rtx_def*, rtx_def*) () #1 0x0000000000eaf44d in simplify_binary_operation(rtx_code, machine_mode, rtx_def*, rtx_def*) () #2 0x0000000001779ba1 in combine_simplify_rtx(rtx_def*, machine_mode, int, int) () #3 0x000000000177443c in subst(rtx_def*, rtx_def*, rtx_def*, int, int, int) () #4 0x000000000177413d in subst(rtx_def*, rtx_def*, rtx_def*, int, int, int) () #5 0x000000000177413d in subst(rtx_def*, rtx_def*, rtx_def*, int, int, int) () #6 0x0000000001779eaa in combine_simplify_rtx(rtx_def*, machine_mode, int, int) () #7 0x000000000177443c in subst(rtx_def*, rtx_def*, rtx_def*, int, int, int) () #8 0x0000000001779ee5 in combine_simplify_rtx(rtx_def*, machine_mode, int, int) () <…> #171156 0x0000000001779ee5 in combine_simplify_rtx(rtx_def*, machine_mode, int, int) () #171157 0x000000000177443c in subst(rtx_def*, rtx_def*, rtx_def*, int, int, int) () #171158 0x000000000177413d in subst(rtx_def*, rtx_def*, rtx_def*, int, int, int) () #171159 0x0000000001772bfb in subst(rtx_def*, rtx_def*, rtx_def*, int, int, int) () #171160 0x0000000001767ada in try_combine(rtx_insn*, rtx_insn*, rtx_insn*, rtx_insn*, int*, rtx_insn*) () #171161 0x0000000001762fea in combine_instructions(rtx_insn*, unsigned int) () #171162 0x00000000017625b9 in rest_of_handle_combine() () #171163 0x0000000001762565 in (anonymous namespace)::pass_combine::execute(function*) () #171164 0x0000000000dbbbd6 in execute_one_pass(opt_pass*) () #171165 0x0000000000dbc74b in execute_pass_list_1(opt_pass*) () #171166 0x0000000000dbc774 in execute_pass_list_1(opt_pass*) () #171167 0x0000000000dac811 in execute_pass_list(function*, opt_pass*) () #171168 0x0000000000904e8f in cgraph_node::expand() () #171169 0x0000000000909bf8 in expand_all_functions() () #171170 0x0000000000908bff in symbol_table::compile() () #171171 0x0000000000909dc2 in symbol_table::finalize_compilation_unit() () #171172 0x0000000000ef3262 in compile_file() () #171173 0x0000000000ef1c86 in do_compile() () #171174 0x0000000000ef169a in toplev::main(int, char**) () #171175 0x000000000190c540 in main ()
combine goes into infinite recursion inside this call: newpat = subst (newpat, i0dest, i0src, 0, 0, 0); The args of the failing subst are: x: (parallel [ (set (reg:SI 181) (plus:SI (ltu:SI (plus:SI (reg:SI 165) (reg:SI 174 [ t9.0_1+4 ])) (reg:SI 165)) (reg:SI 173 [ t9.0_1 ]))) (clobber (reg:SI 76 ca)) ]) from: (reg:SI 174 [ t9.0_1+4 ]) to: (if_then_else:SI (eq (reg:CC 185) (const_int 0 [0])) (reg:SI 165) (reg:SI 174 [ t9.0_1+4 ]))
*** Bug 72746 has been marked as a duplicate of this bug. ***
Looks like if_then_else_cond manages to return a false_rtx identical to the original one, and we try to simplify it again.
Maybe we just need to test for that condition, even though it's ugly. However, I think there are some other improvements we could make here. Part of the problem seems to be what if_then_else_cond does on this rtx: (plus:SI (if_then_else:SI (eq (reg:CC 185) (const_int 0 [0])) (reg:SI 165) (reg:SI 174 [ t9.0_1+4 ])) (reg:SI 165)) Reg 165 is known to be zero or one, so it gets turned into a condition, and we have two different conditions on the operands. That causes us to fail to make the fairly obvious transformation to cond = reg:CC 185 true_rtx = (plus r165 r165) false_rtx = (plus r174 r165) I'm testing the following, which tries to undo such transformation of plain REG if that seems it'll enable other transformations which are more likely to be beneficial. It makes the crash go away. Index: combine.c =================================================================== --- combine.c (revision 242958) +++ combine.c (working copy) @@ -9031,11 +9031,31 @@ if_then_else_cond (rtx x, rtx *ptrue, rt the same value, compute the new true and false values. */ else if (BINARY_P (x)) { - cond0 = if_then_else_cond (XEXP (x, 0), &true0, &false0); - cond1 = if_then_else_cond (XEXP (x, 1), &true1, &false1); + rtx op0 = XEXP (x, 0); + rtx op1 = XEXP (x, 1); + cond0 = if_then_else_cond (op0, &true0, &false0); + cond1 = if_then_else_cond (op1, &true1, &false1); + + if ((cond0 != 0 && cond1 != 0 && !rtx_equal_p (cond0, cond1)) + && (REG_P (op0) || REG_P (op1))) + { + /* Try to enable a simplification by undoing work done by + if_then_else_cond if it converted a REG into something more + complex. */ + if (REG_P (op0)) + { + cond0 = 0; + true0 = false0 = op0; + } + else + { + cond1 = 0; + true1 = false1 = op1; + } + } if ((cond0 != 0 || cond1 != 0) - && ! (cond0 != 0 && cond1 != 0 && ! rtx_equal_p (cond0, cond1))) + && ! (cond0 != 0 && cond1 != 0 && !rtx_equal_p (cond0, cond1))) { /* If if_then_else_cond returned zero, then true/false are the same rtl. We must copy one of them to prevent invalid rtl
I am using the following, which also fixes the infinite loop, and seems to not regress code quality much at all (I found *one* pattern where it made things one machine insn worse, involving a define_insn_and_split (with cost 0, so any finite cost is better -- combine did manage to do something that is better according to its costs!) But I am worried something similar then needs to be done to true_rtx, and I don't see what. === diff --git a/gcc/combine.c b/gcc/combine.c index c7255f0..ecdd3fd 100644 --- a/gcc/combine.c +++ b/gcc/combine.c @@ -5658,7 +5658,7 @@ combine_simplify_rtx (rtx x, machine_mode op0_mode, int in here since true_rtx or false_rtx might share RTL with x as a result of the if_then_else_cond call above. */ true_rtx = subst (copy_rtx (true_rtx), pc_rtx, pc_rtx, 0, 0, 0); - false_rtx = subst (copy_rtx (false_rtx), pc_rtx, pc_rtx, 0, 0, 0); + false_rtx = subst (copy_rtx (false_rtx), cond, const0_rtx, 0, 0, 0); /* If true_rtx and false_rtx are not general_operands, an if_then_else is unlikely to be simpler. */ ===
*** Bug 77345 has been marked as a duplicate of this bug. ***
Author: bernds Date: Mon Jan 23 16:30:55 2017 New Revision: 244817 URL: https://gcc.gnu.org/viewcvs?rev=244817&root=gcc&view=rev Log: PR rtl-optimization/71724 * combine.c (if_then_else_cond): Look for situations where it is beneficial to undo the work of one of the recursive calls. Modified: trunk/gcc/ChangeLog trunk/gcc/combine.c
So I believe the consensus was we want both patches, or variants thereof, so I'm leaving this open, but removing the regression marker.